Skip to content

Commit

Permalink
Merge pull request #764 from fei-protocol/release/2.8.0
Browse files Browse the repository at this point in the history
Release/2.8.0
  • Loading branch information
Caleb Ditchfield authored Apr 29, 2022
2 parents 5068dad + 927cc05 commit e71269c
Show file tree
Hide file tree
Showing 39 changed files with 3,370 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pragma solidity ^0.8.4;
* @notice RariGovernanceTokenUniswapDistributor distributes RGT (Rari Governance Token) to Uniswap LP token holders.
*/
interface RariGovernanceTokenUniswapDistributor {
function setDistributionEndBlock() external;

function distributionEndBlock() external view returns (uint256);

function getRgtDistributed(uint256 blockNumber)
Expand Down
19 changes: 14 additions & 5 deletions contracts/metagov/AngleDelegatorPCVDeposit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,23 @@ pragma solidity ^0.8.0;
import "./SnapshotDelegatorPCVDeposit.sol";
import "./utils/VoteEscrowTokenManager.sol";
import "./utils/LiquidityGaugeManager.sol";
import "./utils/OZGovernorVoter.sol";
import "./utils/GovernorVoter.sol";

/// @title ANGLE Token PCV Deposit
/// @author Fei Protocol
contract AngleDelegatorPCVDeposit is
SnapshotDelegatorPCVDeposit,
VoteEscrowTokenManager,
LiquidityGaugeManager,
OZGovernorVoter
GovernorVoter
{
address private constant ANGLE_TOKEN =
0x31429d1856aD1377A8A0079410B297e1a9e214c2;
address private constant ANGLE_VE_TOKEN =
0x0C462Dbb9EC8cD1630f1728B2CFD2769d09f0dd5;
address private constant ANGLE_GAUGE_MANAGER =
0x9aD7e7b0877582E14c17702EecF49018DD6f2367;
bytes32 private constant ANGLE_SNAPSHOT_SPACE =
keccak256("anglegovernance.eth");
bytes32 private constant ANGLE_SNAPSHOT_SPACE = "anglegovernance.eth";

/// @notice ANGLE token manager
/// @param _core Fei Core for reference
Expand All @@ -39,11 +38,21 @@ contract AngleDelegatorPCVDeposit is
4 * 365 * 86400 // vote-escrow time = 4 years
)
LiquidityGaugeManager(ANGLE_GAUGE_MANAGER)
OZGovernorVoter()
GovernorVoter()
{}

/// @notice returns total balance of PCV in the Deposit
function balance() public view override returns (uint256) {
return _totalTokensManaged(); // liquid and vote-escrowed tokens
}

/// @notice returns the token address to be staked in the given gauge
function _tokenStakedInGauge(address gaugeAddress)
internal
view
override
returns (address)
{
return ILiquidityGauge(gaugeAddress).staking_token();
}
}
2 changes: 2 additions & 0 deletions contracts/metagov/SnapshotDelegatorPCVDeposit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ contract SnapshotDelegatorPCVDeposit is PCVDeposit {
external
onlyTribeRole(TribeRoles.METAGOVERNANCE_VOTE_ADMIN)
{
DELEGATE_REGISTRY.clearDelegate(spaceId);
spaceId = _spaceId;
_delegate(delegate);
}

/// @notice sets the snapshot delegate
Expand Down
46 changes: 46 additions & 0 deletions contracts/metagov/VeBalDelegatorPCVDeposit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

import "./SnapshotDelegatorPCVDeposit.sol";
import "./utils/VoteEscrowTokenManager.sol";
import "./utils/LiquidityGaugeManager.sol";
import "./utils/GovernorVoter.sol";

/// @title 80-BAL-20-WETH BPT PCV Deposit
/// @author Fei Protocol
contract VeBalDelegatorPCVDeposit is
SnapshotDelegatorPCVDeposit,
VoteEscrowTokenManager,
LiquidityGaugeManager,
GovernorVoter
{
address public constant B_80BAL_20WETH =
0x5c6Ee304399DBdB9C8Ef030aB642B10820DB8F56;
address public constant VE_BAL = 0xC128a9954e6c874eA3d62ce62B468bA073093F25;
address public constant BALANCER_GAUGE_CONTROLLER =
0xC128468b7Ce63eA702C1f104D55A2566b13D3ABD;

/// @notice veBAL token manager
/// @param _core Fei Core for reference
/// @param _initialDelegate initial delegate for snapshot votes
constructor(address _core, address _initialDelegate)
SnapshotDelegatorPCVDeposit(
_core,
IERC20(B_80BAL_20WETH), // token used in reporting
"balancer.eth", // initial snapshot spaceId
_initialDelegate
)
VoteEscrowTokenManager(
IERC20(B_80BAL_20WETH), // liquid token
IVeToken(VE_BAL), // vote-escrowed token
365 * 86400 // vote-escrow time = 1 year
)
LiquidityGaugeManager(BALANCER_GAUGE_CONTROLLER)
GovernorVoter()
{}

/// @notice returns total balance of PCV in the Deposit
function balance() public view override returns (uint256) {
return _totalTokensManaged(); // liquid and vote-escrowed tokens
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@ pragma solidity ^0.8.0;
import "../../refs/CoreRef.sol";
import "../../core/TribeRoles.sol";

interface IOZGovernor {
interface IMetagovGovernor {
// OpenZeppelin Governor propose signature
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) external returns (uint256 proposalId);

// Governor Bravo propose signature
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) external returns (uint256 proposalId);

function castVote(uint256 proposalId, uint8 support)
external
returns (uint256 weight);
Expand All @@ -21,21 +31,44 @@ interface IOZGovernor {

/// @title Abstract class to interact with an OZ governor.
/// @author Fei Protocol
abstract contract OZGovernorVoter is CoreRef {
abstract contract GovernorVoter is CoreRef {
// Events
event Proposed(IOZGovernor indexed governor, uint256 proposalId);
event Proposed(IMetagovGovernor indexed governor, uint256 proposalId);
event Voted(
IOZGovernor indexed governor,
IMetagovGovernor indexed governor,
uint256 proposalId,
uint256 weight,
uint8 support
);

/// @notice propose a new proposal on the target governor.
function propose(
IOZGovernor governor,
/// @notice propose a new proposal on the target OZ governor.
function proposeOZ(
IMetagovGovernor governor,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
)
external
onlyTribeRole(TribeRoles.METAGOVERNANCE_VOTE_ADMIN)
returns (uint256)
{
uint256 proposalId = governor.propose(
targets,
values,
calldatas,
description
);
emit Proposed(governor, proposalId);
return proposalId;
}

/// @notice propose a new proposal on the target Bravo governor.
function proposeBravo(
IMetagovGovernor governor,
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
)
Expand All @@ -46,6 +79,7 @@ abstract contract OZGovernorVoter is CoreRef {
uint256 proposalId = governor.propose(
targets,
values,
signatures,
calldatas,
description
);
Expand All @@ -55,7 +89,7 @@ abstract contract OZGovernorVoter is CoreRef {

/// @notice cast a vote on a given proposal on the target governor.
function castVote(
IOZGovernor governor,
IMetagovGovernor governor,
uint256 proposalId,
uint8 support
)
Expand Down
24 changes: 22 additions & 2 deletions contracts/metagov/utils/LiquidityGaugeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ interface ILiquidityGauge {

function balanceOf(address) external view returns (uint256);

// curve & balancer use lp_token()
function lp_token() external view returns (address);

// angle use staking_token()
function staking_token() external view returns (address);

function reward_tokens(uint256 i) external view returns (address token);
Expand Down Expand Up @@ -80,6 +84,16 @@ abstract contract LiquidityGaugeManager is CoreRef {
emit GaugeControllerChanged(oldController, gaugeController);
}

/// @notice returns the token address to be staked in the given gauge
function _tokenStakedInGauge(address gaugeAddress)
internal
view
virtual
returns (address)
{
return ILiquidityGauge(gaugeAddress).lp_token();
}

/// @notice Set gauge for a given token.
/// @param token the token address to stake in gauge
/// @param gaugeAddress the address of the gauge where to stake token
Expand All @@ -88,7 +102,7 @@ abstract contract LiquidityGaugeManager is CoreRef {
onlyTribeRole(TribeRoles.METAGOVERNANCE_GAUGE_ADMIN)
{
require(
ILiquidityGauge(gaugeAddress).staking_token() == token,
_tokenStakedInGauge(gaugeAddress) == token,
"LiquidityGaugeManager: wrong gauge for token"
);
require(
Expand Down Expand Up @@ -181,7 +195,13 @@ abstract contract LiquidityGaugeManager is CoreRef {

/// @notice Claim rewards associated to a gauge where this contract stakes
/// tokens.
function claimGaugeRewards(address gaugeAddress) public whenNotPaused {
function claimGaugeRewards(address token) public whenNotPaused {
address gaugeAddress = tokenToGauge[token];
require(
gaugeAddress != address(0),
"LiquidityGaugeManager: token has no gauge configured"
);

uint256 nTokens = ILiquidityGauge(gaugeAddress).reward_count();
address[] memory tokens = new address[](nTokens);
uint256[] memory amounts = new uint256[](nTokens);
Expand Down
4 changes: 4 additions & 0 deletions contracts/metagov/utils/VoteEscrowTokenManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ interface IVeToken {
function locked__end(address) external view returns (uint256);

function checkpoint() external;

function commit_smart_wallet_checker(address) external;

function apply_smart_wallet_checker() external;
}

/// @title Vote-escrowed Token Manager
Expand Down
9 changes: 9 additions & 0 deletions contracts/mock/MockGovernorVoter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.4;

import "./MockCoreRef.sol";
import "../metagov/utils/GovernorVoter.sol";

contract MockGovernorVoter is GovernorVoter, MockCoreRef {
constructor(address core) MockCoreRef(core) GovernorVoter() {}
}
9 changes: 0 additions & 9 deletions contracts/mock/MockOZGovernorVoter.sol

This file was deleted.

8 changes: 7 additions & 1 deletion contracts/pcv/PCVDeposit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,19 @@ abstract contract PCVDeposit is IPCVDeposit, CoreRef {

function balance() public view virtual override returns (uint256);

function balanceReportedIn() public view virtual override returns (address);

function resistantBalanceAndFei()
public
view
virtual
override
returns (uint256, uint256)
{
return (balance(), 0);
uint256 tokenBalance = balance();
return (
tokenBalance,
balanceReportedIn() == address(fei()) ? tokenBalance : 0
);
}
}
57 changes: 57 additions & 0 deletions contracts/pcv/angle/AngleGaugeLens.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.10;

import "../../metagov/utils/LiquidityGaugeManager.sol";
import "../IPCVDepositBalances.sol";

/// @title AngleGaugeLens
/// @author Fei Protocol
/// @notice a contract to read tokens held in a gauge.
/// Angle has a small modification in their Curve fork : they name a
/// variable staking_token() instead of lp_token() as in the original Curve code.
contract AngleGaugeLens is IPCVDepositBalances {
/// @notice FEI token address
address private constant FEI = 0x956F47F50A910163D8BF957Cf5846D573E7f87CA;

/// @notice the gauge inspected
address public immutable gaugeAddress;

/// @notice the address of the contract staking in the gauge
address public immutable stakerAddress;

/// @notice the token the lens reports balances in
address public immutable override balanceReportedIn;

constructor(address _gaugeAddress, address _stakerAddress) {
gaugeAddress = _gaugeAddress;
stakerAddress = _stakerAddress;
balanceReportedIn = ILiquidityGauge(_gaugeAddress).staking_token();
}

/// @notice returns the amount of tokens staked by stakerAddress in
/// the gauge gaugeAddress.
function balance() public view override returns (uint256) {
return ILiquidityGauge(gaugeAddress).balanceOf(stakerAddress);
}

/// @notice returns the amount of tokens staked by stakerAddress in
/// the gauge gaugeAddress.
/// In the case where an LP token between XYZ and FEI is staked in
/// the gauge, this lens reports the amount of LP tokens staked, not the
/// underlying amounts of XYZ and FEI tokens held within the LP tokens.
/// This lens can be coupled with another lens in order to compute the
/// underlying amounts of FEI and XYZ held inside the LP tokens.
function resistantBalanceAndFei()
public
view
override
returns (uint256, uint256)
{
uint256 stakedBalance = balance();
if (balanceReportedIn == FEI) {
return (stakedBalance, stakedBalance);
} else {
return (stakedBalance, 0);
}
}
}
Loading

0 comments on commit e71269c

Please sign in to comment.