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

Kasper initial reviews #16

Closed
wants to merge 1 commit into from
Closed

Kasper initial reviews #16

wants to merge 1 commit into from

Conversation

haythemsellami
Copy link
Member

No description provided.

@@ -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?
Copy link
Member Author

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?
Copy link
Member Author

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
Copy link
Member Author

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.

Comment on lines +119 to 122
// @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)] =
Copy link
Member Author

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?
Copy link
Member Author

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
Copy link
Member Author

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?

Copy link
Contributor

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?
Copy link
Member Author

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?
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

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.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix

Comment on lines +442 to +444
// @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

Copy link
Member Author

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?
Copy link
Member Author

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
Copy link
Member Author

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?
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

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

Comment on lines +593 to +595
// @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
Copy link
Member Author

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.

Comment on lines +600 to +601
// @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
Copy link
Member Author

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

Copy link
Contributor

@kasperpawlowski kasperpawlowski Jun 6, 2024

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

Comment on lines +633 to +635
// @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
Copy link
Member Author

@haythemsellami haythemsellami Jun 4, 2024

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.

Copy link
Contributor

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 >= ?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Comment on lines +318 to +320
// @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
Copy link
Member Author

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?

Copy link
Contributor

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

@haythemsellami
Copy link
Member Author

Made fixes in this PR #17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants