-
Notifications
You must be signed in to change notification settings - Fork 4
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
Kasper initial reviews #16
Conversation
@@ -51,7 +51,7 @@ abstract contract BalanceForwarder is IBalanceForwarder { | |||
isBalanceForwarderEnabled[_sender] = true; | |||
IBalanceTracker(balanceTracker).balanceTrackerHook(_sender, _senderBalance, false); | |||
|
|||
emit EnableBalanceForwarder(_sender); | |||
emit EnableBalanceForwarder(_sender); // @review: do we want to emit the event even if no state change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah will update this.
@@ -63,6 +63,6 @@ abstract contract BalanceForwarder is IBalanceForwarder { | |||
isBalanceForwarderEnabled[_sender] = false; | |||
IBalanceTracker(balanceTracker).balanceTrackerHook(_sender, 0, false); | |||
|
|||
emit DisableBalanceForwarder(_sender); | |||
emit DisableBalanceForwarder(_sender); // @review: do we want to emit the event even if no state change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, will update.
@@ -47,7 +47,7 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
ESRSlot internal esrSlot; | |||
|
|||
/// @dev Total amount of _asset deposited into FourSixTwoSixAgg contract | |||
uint256 public totalAssetsDeposited; | |||
uint256 public totalAssetsDeposited; // @review: this should rather be internal not to be misleading |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would keep it public, no harm in providing more data to the off-chain world, also may help if someone want to know how much interest is smeared to the deposit.
// @review: why don't we simplify the inteface here? the cash strategy can be passed in the arrays, no need for additional | ||
// _initialCashAllocationPoints parameter and special handling | ||
|
||
strategies[address(0)] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to be explicit I think in this case, and make it clear that this is a separate cash reserve than the rest of the strategies array...
@@ -125,6 +128,10 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
strategies[_initialStrategies[i]] = | |||
Strategy({allocated: 0, allocationPoints: uint120(_initialStrategiesAllocationPoints[i]), active: true}); | |||
|
|||
// @review: shall we check that the strategy is an ERC4626 vault same as we do in addStrategy? | |||
// @review: shouldn't we add the strategy to the withdrawal queue? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes withdrawalQueue
here is missing.
@@ -125,6 +128,10 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
strategies[_initialStrategies[i]] = | |||
Strategy({allocated: 0, allocationPoints: uint120(_initialStrategiesAllocationPoints[i]), active: true}); | |||
|
|||
// @review: shall we check that the strategy is an ERC4626 vault same as we do in addStrategy? | |||
// @review: shouldn't we add the strategy to the withdrawal queue? | |||
// @review: we should prevent strategy duplicates, otherwise the accounting might get messed up |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a diff between having a strategy with 1 allocation config vs multiples?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so. you will write to strategies
multiple times if there are duplicates, overriding the previously set setting. at the same time, you'll be increasing totalAllocationPoints
.
@@ -166,6 +173,7 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
for (uint256 i; i < _strategies.length; ++i) { | |||
_rebalance(_strategies[i]); | |||
} | |||
// @review: wouldn't it be better to gulp just once here rather than on every rebalance? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is updated already.
@@ -426,10 +451,11 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
IERC4626 strategy = IERC4626(withdrawalQueue[i]); | |||
|
|||
_harvest(address(strategy)); | |||
_gulp(); | |||
_gulp(); // @review: wouldn't it be more efficient to gulp just once after the loop? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is updated.
@@ -107,15 +107,18 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
address _asset, | |||
string memory _name, | |||
string memory _symbol, | |||
uint256 _initialCashAllocationPoints, | |||
uint256 _initialCashAllocationPoints, // @review: should be uint120 or checked if it's <= type(uint120).max |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix.
address[] memory _initialStrategies, | ||
uint256[] memory _initialStrategiesAllocationPoints | ||
uint256[] memory _initialStrategiesAllocationPoints // @review: should be array of uint120 or checked if each element is <= type(uint120).max |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix.
@@ -251,6 +259,9 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
/// @dev Can only be called by an address that have the STRATEGY_REMOVER_ROLE | |||
/// @param strategy Address of the strategy | |||
function removeStrategy(address strategy) external nonReentrant onlyRole(STRATEGY_REMOVER_ROLE) { | |||
// @review: protect against mistakenly removing cash strategy. if address(0) passed, withdrawalQueue will get popped anyways. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will fix
// @review: why don't check if the contract has enough assets to withdraw at this point? | ||
// it would be at least one SLOAD less if no need to enter the loop | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored the whole _withdraw()
@@ -426,10 +451,11 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
IERC4626 strategy = IERC4626(withdrawalQueue[i]); | |||
|
|||
_harvest(address(strategy)); | |||
_gulp(); | |||
_gulp(); // @review: wouldn't it be more efficient to gulp just once after the loop? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated already.
|
||
Strategy storage strategyStorage = strategies[address(strategy)]; | ||
|
||
// @review: seems like a maxWithdraw might be better suited here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.
@@ -438,7 +464,7 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
|
|||
// Update allocated assets | |||
strategyStorage.allocated -= uint120(withdrawAmount); | |||
totalAllocated -= withdrawAmount; | |||
totalAllocated -= withdrawAmount; // @review: why not write to storage once after the loop? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will revisit this later, need to see if there is any weird impact on negative yield accounting when harvesting.
@@ -482,7 +508,7 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
|
|||
// Harvest profits, also gulps and updates interest | |||
_harvest(_strategy); | |||
_gulp(); | |||
_gulp(); // @review: if _rebalance called in the loop, we'll gulp multiple times |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
@@ -553,6 +580,7 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
// TODO possible performance fee | |||
} else { | |||
// TODO handle losses | |||
// @review: maybe better to do nothing than revert? not sure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented now a better handling for negative yield
// @review: will shares of this aggregator be used as collateral? | ||
// if so, it might be worth to handle it the same way as we do in the EVK and forfeit recent rewards if in liquidation: | ||
// https://github.com/euler-xyz/euler-vault-kit/blob/master/src/EVault/shared/BalanceUtils.sol#L57-L63 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we are planning to use it as collateral.
// @review: it seems that OZ allows self-transfers. if so, add check for to != from. | ||
// if they're equal, the hook was already called above |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I think we should just ignore hook's call for self-transfers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's always good to update the tracker frequently for the benefit of everyone earning rewards, even if there was no actual value transfer
// @review: currently we're using _msgSender() also for access control. do we want the EVC operators and sub-accounts to | ||
// to be used for access control? if not, we need to override _checkRole and apply additional checks i.e. as it's done here: | ||
// https://github.com/euler-xyz/euler-vault-kit/blob/master/src/EVault/shared/EVCClient.sol#L62-L78 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be fine, also better to keep any EVC stuff abstracted away from here and have it as generic as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note though that if it's not done, it might be very hard to verify the roles. this is because someone can delegate the control to i.e. operator via the EVC which is not easy to spot when analyzing. this is the reason why we decided to lock it down in the EVK, it's safer
@@ -576,7 +609,7 @@ contract FourSixTwoSixAgg is BalanceForwarder, EVCUtil, ERC4626, AccessControlEn | |||
/// @return uint256 accrued interest | |||
function interestAccruedFromCache(ESRSlot memory esrSlotCache) internal view returns (uint256) { | |||
// If distribution ended, full amount is accrued | |||
if (block.timestamp > esrSlotCache.interestSmearEnd) { | |||
if (block.timestamp > esrSlotCache.interestSmearEnd) { // @review: wouldn't it be better with >= ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
// @review: do we want to override _convertToShares and _convertToAssets to maintain | ||
// the same level of exchange rate manipulation protection as for other products? | ||
// see: https://github.com/euler-xyz/euler-vault-kit/blob/master/src/Synths/EulerSavingsRate.sol#L177-L183 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the default OZ implementation not enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it won't be used as collateral (and you already said it won't), it should be fine
Made fixes in this PR #17 |
No description provided.