Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Commit

Permalink
Update rebase around the exact reward token for CometRewards
Browse files Browse the repository at this point in the history
  • Loading branch information
kphed committed Nov 14, 2023
1 parent 85c1ad2 commit 874960d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 55 deletions.
82 changes: 27 additions & 55 deletions src/BrrETH.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Ownable} from "solady/auth/Ownable.sol";
import {ERC4626} from "solady/tokens/ERC4626.sol";
import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";
import {IComet} from "src/interfaces/IComet.sol";
import {ICometRewards} from "src/interfaces/ICometRewards.sol";
import {IRouter} from "src/interfaces/IRouter.sol";

contract BrrETH is Ownable, ERC4626 {
contract BrrETH is ERC4626 {
using SafeTransferLib for address;

string private constant _NAME = "Brrito-Compound WETH";
Expand All @@ -27,16 +26,10 @@ contract BrrETH is Ownable, ERC4626 {

error InvalidAssets();

constructor(address initialOwner) {
_initializeOwner(initialOwner);

constructor() {
_WETH.safeApproveWithRetry(_COMET, type(uint256).max);
}

function transferOwnership(address) public payable override {}

function renounceOwnership() public payable override {}

function name() public pure override returns (string memory) {
return _NAME;
}
Expand Down Expand Up @@ -82,55 +75,34 @@ contract BrrETH is Ownable, ERC4626 {
emit Withdraw(by, to, owner, assets, shares);
}

function rebaseTokens() external view returns (address[] memory) {
return _rebaseTokens;
}

function addRebaseToken(address rebaseToken) external onlyOwner {
// Enable the token to be swapped by the router when rebasing.
rebaseToken.safeApproveWithRetry(address(_ROUTER), type(uint256).max);

_rebaseTokens.push(rebaseToken);

emit AddRebaseToken(rebaseToken);
}

function removeRebaseToken(uint256 index) external onlyOwner {
address removedRebaseToken = _rebaseTokens[index];

unchecked {
// Length should be checked by the caller.
uint256 lastIndex = _rebaseTokens.length - 1;

if (index != lastIndex)
_rebaseTokens[index] = _rebaseTokens[lastIndex];

_rebaseTokens.pop();
}

emit RemoveRebaseToken(removedRebaseToken);
}

// Claim rewards and convert them into the vault asset.
function rebase() external {
_COMET_REWARDS.claim(_COMET, address(this), true);

uint256 tokensLength = _rebaseTokens.length;

for (uint256 i = 0; i < tokensLength; ++i) {
address token = _rebaseTokens[i];
uint256 tokenBalance = token.balanceOf(address(this));

if (tokenBalance == 0) continue;

(uint256 index, uint256 output) = _ROUTER.getSwapOutput(
keccak256(abi.encodePacked(token, _WETH)),
tokenBalance
);

_ROUTER.swap(token, _WETH, tokenBalance, output, index, address(0));
}

IComet(_COMET).supply(_WETH, _WETH.balanceOf(address(this)));
ICometRewards.RewardConfig memory rewardConfig = _COMET_REWARDS
.rewardConfig(_COMET);
uint256 tokenBalance = rewardConfig.token.balanceOf(address(this));

if (tokenBalance == 0) return;

// Fetching the quote onchain means that we're subject to front/back-running but the
// assumption is that we will rebase so frequently that the rewards won't justify the effort.
(uint256 index, uint256 output) = _ROUTER.getSwapOutput(
keccak256(abi.encodePacked(rewardConfig.token, _WETH)),
tokenBalance
);

IComet(_COMET).supply(
_WETH,
// `swap` returns the entire WETH amount received from the swap.
_ROUTER.swap(
rewardConfig.token,
_WETH,
tokenBalance,
output,
index,
address(0)
)
);
}
}
10 changes: 10 additions & 0 deletions src/interfaces/ICometRewards.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,15 @@
pragma solidity ^0.8.0;

interface ICometRewards {
struct RewardConfig {
address token;
uint64 rescaleFactor;
bool shouldUpscale;
// Note: We define new variables after existing variables to keep interface backwards-compatible
uint256 multiplier;
}

function claim(address comet, address src, bool shouldAccrue) external;

function rewardConfig(address) external view returns (RewardConfig memory);
}

0 comments on commit 874960d

Please sign in to comment.