Skip to content

Commit

Permalink
OGN Buyback (#2033)
Browse files Browse the repository at this point in the history
* OGN Buyback

* Fix unit test deployment

* Move deployment file

* Make tests less flaky
  • Loading branch information
shahthepro authored May 8, 2024
1 parent a7457ec commit bbbd918
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 104 deletions.
56 changes: 28 additions & 28 deletions contracts/contracts/buyback/BaseBuyback.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ abstract contract BaseBuyback is Initializable, Strategizable {
event TreasuryManagerUpdated(address indexed _address);
event CVXShareBpsUpdated(uint256 bps);

// Emitted whenever OUSD/OETH is swapped for OGV/CVX or any other token
// Emitted whenever OUSD/OETH is swapped for OGN/CVX or any other token
event OTokenBuyback(
address indexed oToken,
address indexed swappedFor,
uint256 swapAmountIn,
uint256 minExpected
uint256 amountOut
);

// Address of 1-inch Swap Router
Expand All @@ -39,7 +39,7 @@ abstract contract BaseBuyback is Initializable, Strategizable {
// slither-disable-next-line constable-states
address private __deprecated_weth9;

// Address that receives OGV after swaps
// Address that receives OGN after swaps
address public rewardsSource;

// Address that receives all other tokens after swaps
Expand All @@ -49,12 +49,12 @@ abstract contract BaseBuyback is Initializable, Strategizable {
uint256 private __deprecated_treasuryBps;

address public immutable oToken;
address public immutable ogv;
address public immutable ogn;
address public immutable cvx;
address public immutable cvxLocker;

// Amount of `oToken` balance to use for OGV buyback
uint256 public balanceForOGV;
// Amount of `oToken` balance to use for OGN buyback
uint256 public balanceForOGN;

// Amount of `oToken` balance to use for CVX buyback
uint256 public balanceForCVX;
Expand All @@ -64,15 +64,15 @@ abstract contract BaseBuyback is Initializable, Strategizable {

constructor(
address _oToken,
address _ogv,
address _ogn,
address _cvx,
address _cvxLocker
) {
// Make sure nobody owns the implementation contract
_setGovernor(address(0));

oToken = _oToken;
ogv = _ogv;
ogn = _ogn;
cvx = _cvx;
cvxLocker = _cvxLocker;
}
Expand Down Expand Up @@ -118,9 +118,9 @@ abstract contract BaseBuyback is Initializable, Strategizable {
if (oldRouter != address(0)) {
// Remove allowance of old router, if any

if (IERC20(ogv).allowance(address(this), oldRouter) != 0) {
if (IERC20(ogn).allowance(address(this), oldRouter) != 0) {
// slither-disable-next-line unused-return
IERC20(ogv).safeApprove(oldRouter, 0);
IERC20(ogn).safeApprove(oldRouter, 0);
}

if (IERC20(cvx).allowance(address(this), oldRouter) != 0) {
Expand All @@ -133,7 +133,7 @@ abstract contract BaseBuyback is Initializable, Strategizable {
}

/**
* @dev Sets the address that receives the OGV buyback rewards
* @dev Sets the address that receives the OGN buyback rewards
* @param _address Address
*/
function setRewardsSource(address _address) external onlyGovernor {
Expand Down Expand Up @@ -176,27 +176,27 @@ abstract contract BaseBuyback is Initializable, Strategizable {

/**
* @dev Computes the split of oToken balance that can be
* used for OGV and CVX buybacks.
* used for OGN and CVX buybacks.
*/
function _updateBuybackSplits()
internal
returns (uint256 _balanceForOGV, uint256 _balanceForCVX)
returns (uint256 _balanceForOGN, uint256 _balanceForCVX)
{
_balanceForOGV = balanceForOGV;
_balanceForOGN = balanceForOGN;
_balanceForCVX = balanceForCVX;

uint256 totalBalance = IERC20(oToken).balanceOf(address(this));
uint256 unsplitBalance = totalBalance - _balanceForOGV - _balanceForCVX;
uint256 unsplitBalance = totalBalance - _balanceForOGN - _balanceForCVX;

// Check if all balance is accounted for
if (unsplitBalance != 0) {
// If not, split unaccounted balance based on `cvxShareBps`
uint256 addToCVX = (unsplitBalance * cvxShareBps) / 10000;
_balanceForCVX = _balanceForCVX + addToCVX;
_balanceForOGV = _balanceForOGV + unsplitBalance - addToCVX;
_balanceForOGN = _balanceForOGN + unsplitBalance - addToCVX;

// Update storage
balanceForOGV = _balanceForOGV;
balanceForOGN = _balanceForOGN;
balanceForCVX = _balanceForCVX;
}
}
Expand Down Expand Up @@ -231,34 +231,34 @@ abstract contract BaseBuyback is Initializable, Strategizable {

require(amountOut >= minAmountOut, "Higher Slippage");

emit OTokenBuyback(oToken, tokenOut, minAmountOut, amountOut);
emit OTokenBuyback(oToken, tokenOut, oTokenAmount, amountOut);
}

/**
* @dev Swaps `oTokenAmount` to OGV
* @dev Swaps `oTokenAmount` to OGN
* @param oTokenAmount Amount of OUSD/OETH to swap
* @param minOGV Minimum OGV to receive for oTokenAmount
* @param minOGN Minimum OGN to receive for oTokenAmount
* @param swapData 1inch Swap Data
*/
function swapForOGV(
function swapForOGN(
uint256 oTokenAmount,
uint256 minOGV,
uint256 minOGN,
bytes calldata swapData
) external onlyGovernorOrStrategist nonReentrant {
(uint256 _amountForOGV, ) = _updateBuybackSplits();
require(_amountForOGV >= oTokenAmount, "Balance underflow");
(uint256 _amountForOGN, ) = _updateBuybackSplits();
require(_amountForOGN >= oTokenAmount, "Balance underflow");
require(rewardsSource != address(0), "RewardsSource contract not set");

unchecked {
// Subtract the amount to swap from net balance
balanceForOGV = _amountForOGV - oTokenAmount;
balanceForOGN = _amountForOGN - oTokenAmount;
}

uint256 ogvReceived = _swapToken(ogv, oTokenAmount, minOGV, swapData);
uint256 ognReceived = _swapToken(ogn, oTokenAmount, minOGN, swapData);

// Transfer OGV received to RewardsSource contract
// Transfer OGN received to RewardsSource contract
// slither-disable-next-line unchecked-transfer unused-return
IERC20(ogv).transfer(rewardsSource, ogvReceived);
IERC20(ogn).transfer(rewardsSource, ognReceived);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions contracts/deploy/deployActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1279,13 +1279,13 @@ const deployBuyback = async () => {
const oethContractName = isMainnetOrFork ? "OETHBuyback" : "MockBuyback";
const dOUSDBuybackImpl = await deployWithConfirmation(ousdContractName, [
ousd.address,
assetAddresses.OGV,
assetAddresses.OGN,
assetAddresses.CVX,
assetAddresses.CVXLocker,
]);
const dOETHBuybackImpl = await deployWithConfirmation(oethContractName, [
oeth.address,
assetAddresses.OGV,
assetAddresses.OGN,
assetAddresses.CVX,
assetAddresses.CVXLocker,
]);
Expand Down
76 changes: 76 additions & 0 deletions contracts/deploy/mainnet/095_ogn_buyback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const { isFork } = require("../../test/helpers");
const addresses = require("../../utils/addresses");
const {
deploymentWithGovernanceProposal,
deployWithConfirmation,
} = require("../../utils/deploy");

module.exports = deploymentWithGovernanceProposal(
{
deployName: "095_ogn_buyback",
// forceSkip: true,
// onlyOnFork: true, // this is only executed in forked environment
reduceQueueTime: true, // just to solve the issue of later active proposals failing
proposalId: "",
},
async ({ ethers }) => {
const cOETHBuybackProxy = await ethers.getContract("OETHBuybackProxy");
const cOUSDBuybackProxy = await ethers.getContract("BuybackProxy");

const cSwapper = await ethers.getContract("Swapper1InchV5");

// Deploy new OETHBuyback implementation
const dOETHBuybackImpl = await deployWithConfirmation(
"OETHBuyback",
[
addresses.mainnet.OETHProxy,
addresses.mainnet.OGN,
addresses.mainnet.CVX,
addresses.mainnet.CVXLocker,
],
undefined,
true
);

// Deploy new OUSDBuyback implementation
const dOUSDBuybackImpl = await deployWithConfirmation(
"OUSDBuyback",
[
addresses.mainnet.OUSDProxy,
addresses.mainnet.OGN,
addresses.mainnet.CVX,
addresses.mainnet.CVXLocker,
],
undefined,
true
);

await cSwapper.approveAssets([addresses.mainnet.OGN]);

if (!isFork) {
// No Governance action on mainnet
// To be upgraded with the proposal from `ousd-governance` repo
return {
actions: [],
};
}

return {
name: "Upgrade contracts for OGN Buyback",
actions: [
// 1. Upgrade OUSD Buyback to new implementation
{
contract: cOUSDBuybackProxy,
signature: "upgradeTo(address)",
args: [dOUSDBuybackImpl.address],
},
// 2. Upgrade OETH Buyback to new implementation
{
contract: cOETHBuybackProxy,
signature: "upgradeTo(address)",
args: [dOETHBuybackImpl.address],
},
],
};
}
);
Loading

0 comments on commit bbbd918

Please sign in to comment.