Skip to content
Merged
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
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
Copy link
Contributor

Choose a reason for hiding this comment

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

should this include governor bravo compatibility? Vote escrow is a hard action to undo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can add OZGovernor capability (that have a contract ready & tested), but when I asked Kia he said that Balancer does everything with snapshot + multisigs, no governor

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you follow up and make sure they have no intentions of putting anything on-chain?

Copy link
Contributor

Choose a reason for hiding this comment

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

including for example a nope-dao?

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.

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