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

Commit

Permalink
Clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
kphed committed Nov 13, 2023
1 parent 2badefd commit 1aff852
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 178 deletions.
137 changes: 56 additions & 81 deletions src/BrrETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,88 +6,102 @@ 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 {IWETH} from "src/interfaces/IWETH.sol";
import {IRouter} from "src/interfaces/IRouter.sol";

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

string private constant _NAME = "Rebasing Compound ETH";
string private constant _SYMBOL = "brrETH";
address private constant _WETH_ADDR =
0x4200000000000000000000000000000000000006;
address private constant _COMET_ADDR =
address private constant _WETH = 0x4200000000000000000000000000000000000006;
address private constant _COMET =
0x46e6b214b524310239732D51387075E0e70970bf;
IWETH private constant _WETH = IWETH(_WETH_ADDR);
IComet private constant _COMET = IComet(_COMET_ADDR);
ICometRewards private constant _COMET_REWARDS =
ICometRewards(0x123964802e6ABabBE1Bc9547D72Ef1B69B00A6b1);
IRouter private constant _ROUTER =
IRouter(0x635d91a7fae76BD504fa1084e07Ab3a22495A738);
address private constant _ROUTER_REFERRER = address(0);
address[] private _rewardTokens;
address[] private _rebaseTokens;

event AddRewardToken(address);
event RemoveRewardToken(address);

error NoRewardsRemaining();
error AssetsGreaterThanBalance();
event AddRebaseToken(address);
event RemoveRebaseToken(address);

constructor(address initialOwner) {
_initializeOwner(initialOwner);

_WETH_ADDR.safeApprove(_COMET_ADDR, type(uint256).max);
_WETH.safeApproveWithRetry(_COMET, type(uint256).max);
}

function name() public pure override returns (string memory) {
return _NAME;
}

function symbol() public pure override returns (string memory) {
return _SYMBOL;
}

function asset() public pure override returns (address) {
return _COMET;
}

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

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

_rewardTokens.push(rewardToken);
_rebaseTokens.push(rebaseToken);

emit AddRewardToken(rewardToken);
emit AddRebaseToken(rebaseToken);
}

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

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

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

_rewardTokens.pop();
_rebaseTokens.pop();
}

emit RemoveRewardToken(removedRewardToken);
emit RemoveRebaseToken(removedRebaseToken);
}

function rewardTokens() external view returns (address[] memory) {
return _rewardTokens;
}
// Claim rewards and convert them into the vault asset.
function rebase() public {
_COMET_REWARDS.claim(_COMET, address(this), true);

function name() public pure override returns (string memory) {
return _NAME;
}
uint256 tokensLength = _rebaseTokens.length;

function symbol() public pure override returns (string memory) {
return _SYMBOL;
}
for (uint256 i = 0; i < tokensLength; ++i) {
address token = _rebaseTokens[i];
uint256 tokenBalance = token.balanceOf(address(this));

function asset() public pure override returns (address) {
return _COMET_ADDR;
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)));
}

function deposit(
uint256 assets,
address to
) public override returns (uint256 shares) {
if (assets > _COMET_ADDR.balanceOf(msg.sender))
revert AssetsGreaterThanBalance();
if (assets > _COMET.balanceOf(msg.sender)) revert InsufficientBalance();

harvest();
rebase();

shares = previewDeposit(assets);

Expand All @@ -98,56 +112,17 @@ contract BrrETH is Ownable, ERC4626 {
uint256 shares,
address to
) public override returns (uint256 assets) {
harvest();
rebase();

assets = previewMint(shares);

if (assets > _COMET_ADDR.balanceOf(msg.sender))
revert AssetsGreaterThanBalance();
if (assets > _COMET.balanceOf(msg.sender)) revert InsufficientBalance();

_deposit(msg.sender, to, assets, shares);
}

/**
* @notice Claim rewards and convert them into the vault asset.
*/
function harvest() public {
_COMET_REWARDS.claim(_COMET_ADDR, address(this), true);

uint256 tokensLength = _rewardTokens.length;
address token = address(0);
uint256 tokenBalance = 0;
uint256 index = 0;
uint256 output = 0;

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

if (tokenBalance == 0) continue;

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

_ROUTER.swap(
token,
_WETH_ADDR,
tokenBalance,
output,
index,
_ROUTER_REFERRER
);
}

_COMET.supply(_WETH_ADDR, _WETH_ADDR.balanceOf(address(this)));
}

// Overridden to enforce 2-step ownership transfers.
function transferOwnership(
address newOwner
) public payable override onlyOwner {}
function transferOwnership(address) public payable override onlyOwner {}

// Overridden to enforce 2-step ownership transfers.
function renounceOwnership() public payable override onlyOwner {}
Expand Down
21 changes: 9 additions & 12 deletions src/BrrETHDepositor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ import {IComet} from "src/interfaces/IComet.sol";
contract BrrETHDepositor {
using SafeTransferLib for address;

address private constant _WETH_ADDR =
0x4200000000000000000000000000000000000006;
address private constant _COMET_ADDR =
address private constant _WETH = 0x4200000000000000000000000000000000000006;
address private constant _COMET =
0x46e6b214b524310239732D51387075E0e70970bf;
IWETH private constant _WETH = IWETH(_WETH_ADDR);
IComet private constant _COMET = IComet(_COMET_ADDR);
BrrETH public immutable brrETH;

error InvalidAmount();
Expand All @@ -24,8 +21,8 @@ contract BrrETHDepositor {
constructor(address _brrETH) {
brrETH = BrrETH(_brrETH);

_WETH_ADDR.safeApprove(_COMET_ADDR, type(uint256).max);
_COMET_ADDR.safeApprove(_brrETH, type(uint256).max);
_WETH.safeApproveWithRetry(_COMET, type(uint256).max);
_COMET.safeApproveWithRetry(_brrETH, type(uint256).max);
}

/**
Expand All @@ -37,7 +34,7 @@ contract BrrETHDepositor {
if (msg.value == 0) revert InvalidAmount();
if (to == address(0)) revert InvalidAddress();

_WETH.deposit{value: msg.value}();
IWETH(_WETH).deposit{value: msg.value}();

return _supplyAndDeposit(msg.value, to);
}
Expand All @@ -52,17 +49,17 @@ contract BrrETHDepositor {
if (amount == 0) revert InvalidAmount();
if (to == address(0)) revert InvalidAddress();

_WETH_ADDR.safeTransferFrom(msg.sender, address(this), amount);
_WETH.safeTransferFrom(msg.sender, address(this), amount);

return _supplyAndDeposit(amount, to);
}

function _supplyAndDeposit(
uint256 amount,
address to
) private returns (uint256 shares) {
_COMET.supply(_WETH_ADDR, amount);
) private returns (uint256) {
IComet(_COMET).supply(_WETH, amount);

shares = brrETH.deposit(_COMET_ADDR.balanceOf(address(this)), to);
return brrETH.deposit(_COMET.balanceOf(address(this)), to);
}
}
12 changes: 0 additions & 12 deletions src/interfaces/IComet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,5 @@
pragma solidity ^0.8.0;

interface IComet {
struct UserBasic {
int104 principal;
uint64 baseTrackingIndex;
uint64 baseTrackingAccrued;
uint16 assetsIn;
uint8 _reserved;
}

function supply(address asset, uint amount) external;

function userBasic(address user) external view returns (UserBasic memory);

function balanceOf(address account) external view returns (uint256);
}
Loading

0 comments on commit 1aff852

Please sign in to comment.