Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ vote: get voting power from velodrome and extra #671

Merged
merged 1 commit into from
Oct 17, 2023
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
5 changes: 5 additions & 0 deletions .changeset/twenty-peas-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/protocol": patch
---

✨ vote: get voting power from velodrome and extra
3 changes: 2 additions & 1 deletion .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -400,4 +400,5 @@ SwapperTest:testSwapWithKeepAmount() (gas: 201230)
SwapperTest:testSwapWithKeepEqualToValue() (gas: 41783)
SwapperTest:testSwapWithKeepHigherThanValue() (gas: 41804)
SwapperTest:testSwapWithPermit() (gas: 566299)
SwapperTest:testSwapWithPermit2() (gas: 560666)
SwapperTest:testSwapWithPermit2() (gas: 560666)
VotePreviewerTest:testExternalVotes() (gas: 97572)
66 changes: 66 additions & 0 deletions contracts/periphery/VotePreviewer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.17;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { FixedPointMathLib } from "solmate/src/utils/FixedPointMathLib.sol";

/// @title Vote Previewer
/// @notice Contract to be consumed by voting strategies.
contract VotePreviewer {
using FixedPointMathLib for uint256;

/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address public immutable exa;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
IPool public immutable pool;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
IERC20 public immutable gauge;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
IExtraLending public immutable extraLending;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
uint256 public immutable extraReserveId;

/// @custom:oz-upgrades-unsafe-allow constructor
constructor(address exa_, IPool pool_, IERC20 gauge_, IExtraLending extraLending_, uint256 extraReserveId_) {
exa = exa_;
pool = pool_;
gauge = gauge_;
extraLending = extraLending_;
extraReserveId = extraReserveId_;

Check warning on line 29 in contracts/periphery/VotePreviewer.sol

View check run for this annotation

Codecov / codecov/patch

contracts/periphery/VotePreviewer.sol#L25-L29

Added lines #L25 - L29 were not covered by tests
}

function externalVotes(address account) external view returns (uint256 votes) {
uint256 liquidity = pool.balanceOf(account) + gauge.balanceOf(account);
votes += liquidity.mulDivDown(exa == pool.token0() ? pool.reserve0() : pool.reserve1(), pool.totalSupply());

uint256[] memory reserveIds = new uint256[](1);
reserveIds[0] = extraReserveId;
IExtraLending.PositionStatus[] memory e = extraLending.getPositionStatus(reserveIds, account);
votes += extraLending.exchangeRateOfReserve(extraReserveId).mulWadDown(e[0].eTokenStaked + e[0].eTokenUnStaked);
}
}

interface IPool is IERC20 {
function token0() external view returns (address);

function reserve0() external view returns (uint256);

function reserve1() external view returns (uint256);
}

interface IExtraLending {
struct PositionStatus {
uint256 reserveId;
address user;
uint256 eTokenStaked;
uint256 eTokenUnStaked;
uint256 liquidity;
}

function getPositionStatus(
uint256[] memory reserveIds,
address account
) external view returns (PositionStatus[] memory);

function exchangeRateOfReserve(uint256 reserveId) external view returns (uint256);
}
27 changes: 26 additions & 1 deletion deploy/Previewers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,34 @@ import type { DeployFunction } from "hardhat-deploy/types";
import validateUpgrade from "./.utils/validateUpgrade";

const func: DeployFunction = async ({
network: {
config: {
finance: { periphery },
},
},
ethers: {
constants: { AddressZero },
},
deployments: { deploy, get, getOrNull },
getNamedAccounts,
}) => {
const [{ address: auditor }, { address: debtManager }, { address: priceFeedETH }, { deployer }] = await Promise.all([
const [
{ address: auditor },
{ address: debtManager },
{ address: exa },
{ address: exaPool },
{ address: exaGauge },
{ address: priceFeedETH },
{ address: extraLending },
{ deployer },
] = await Promise.all([
get("Auditor"),
get("DebtManager"),
get("EXA"),
getOrNull("EXAPool").then((d) => d ?? { address: AddressZero }),
getOrNull("EXAGauge").then((d) => d ?? { address: AddressZero }),
getOrNull("PriceFeedETH").then((d) => d ?? { address: AddressZero }),
getOrNull("ExtraLending").then((d) => d ?? { address: AddressZero }),
getNamedAccounts(),
]);
await validateUpgrade("Previewer", { args: [auditor, priceFeedETH], envKey: "PREVIEWER" }, async (name, opts) =>
Expand All @@ -25,6 +43,13 @@ const func: DeployFunction = async ({
log: true,
}),
);

await validateUpgrade(
"VotePreviewer",
{ args: [exa, exaPool, exaGauge, extraLending, periphery.extraReserve], envKey: "VOTE_PREVIEWER" },
async (name, opts) =>
deploy(name, { ...opts, proxy: { proxyContract: "TransparentUpgradeableProxy" }, from: deployer, log: true }),
);
};

func.tags = ["Previewers"];
Expand Down
Loading
Loading