Open vany365 opened 2 years ago
denominator
and numerator
.liquidatePosition
(https://github.com/OpenOrg-gg/yearn-euler/blob/master/contracts/Strategy.sol#L232-L254) first check if balanceOfWant() is enough to cover _amountNeeded
.balanceOfWant()
in Lines 137, 260prepareMigration
, we can also migrate existing eulTokens in the strategy.Done
Done.
Unclear - follow up question in tg.
Done.
on Line 239 we check if there is enough, if so we withdraw that amount, otherwise we withdraw the max available and then check the balance. If it was a lack in liquidity we would temporarily count it as a loss, and then recount it as a profit once it was actually available again.
Yes - need to discuss this.
No as discussed in tg.
Didn't add, as some projects once you can claim still have transfers not allowed to start, didn't want to have prepareMigration revert if that's the case and haven't seen a clean standard way to safely check transferability.
subAccountId
in withdraw()
? Will it always be 0 or should this be adjustable or dynamic?adjustPosition
to return if emergency exit is true.eToken.withdraw(0,_amount);
, I would just use that where it's needed. uint256 _wantBal = balanceOfWant();
if (_amountNeeded > _wantBal) {
uint256 _stakedBal = stakedBalance();
if (_stakedBal > 0) {
rewardsContract.withdraw(
Math.min(_stakedBal, _amountNeeded.sub(_wantBal)));
}
uint256 _withdrawnBal = balanceOfWant();
_liquidatedAmount = Math.min(_amountNeeded, _withdrawnBal);
_loss = _amountNeeded.sub(_liquidatedAmount);
} else {
// we have enough balance to cover the liquidation available
return (_amountNeeded, 0);
}
Changes added on branch "Feedback 1.2" - bolded points that need more feedback.
Noted
Should always be 0, every address can have multiple subaccounts they set up to isolate positions. 0 is the master account.
3. Unsure about the purpose on this. Is this just a flag that if=true we do not redeposit?
5. I've pulled this from previous changes Micky added in saying that this way was cleaner. Happy to revert but will let you two debate.
6. Under normal operations, but in the event of issues with the market or a hack then you could be at a non-zero value here, right?
7. They can - my understanding was the practice was if funds are stuck count them as a loss, then if they ever get unstuck count them as a profit later?
8. No, but I was told it was cleaner to create functions for any calls we're using more than once?
Good point. Fixed.
Ok think I have this revised.
Yes, will follow up to discuss.
12. Would we trigger the prepareMigration()
call on a strategy if there was 0? Thought that is a manual call?
13. No, it came in the standard mix, and I thought it would be required? I can remove it if not needed.
Set to only Governance.
Claims aren't live and need to be done with a proof off chain, so no need for harvest trigger.
Holy shit, it's seriously been a week? Good god. 😵💫
_loss
is already zero, because you don't assign it any value anywhere above in prepareReturn
Holy shit, it's seriously been a week? Good god. 😵💫
- yes, exactly
Done
- I'm saying there's nothing to add to it. as in,
_loss
is already zero, because you don't assign it any value anywhere above inprepareReturn
But this is calculating the loss and adding it in right? The line is if the debt of the vault is more than the assets we have, there must be a loss. That loss must be the delta between the two values.
So it starts at 0 but we're adding _vaultDebt.sub(_totalAssets)
if vaultDebt > totalAssets. Otherwise we keep it at 0?
- I think counting stuck funds as a loss is bad practice—instead, I would return partial withdrawals and not assess losses (so you would only get a partial burning of shares for anyone who hits the limit).
I'm not sure how I would structure that; but, I also think I disagree.
Stuck funds are extremely rare and usually only in a problem state, especially with a new protocol that hasn't been around as long as other lending markets like Compound.
I think at early stages it is most likely that stuck funds represent an exploit, or a breakdown of the protocol where the ability to return those assets is uncertain. I think they should be counted as lost until they can be returned in this case.
Otherwise the assets are stuck if they are not counted as a loss, a user will be pulling funds from other strategies in the vault, without us being sure if we will recoup those assets.
It feels like this is something that should be handled on a per protocol basis, based on what can cause stuck funds, and how uncommon it is?
- meh, I guess
- You might still, for instance if you've already returned all assets to the vault but want to keep all of the gain/loss data for the strategy. But I don't need to die on that hill.
- Nah, you can just remove that return line and have it be a blank function
- Makes sense
Other changes are on this PR and I'll keep it rolling with the changes so they are easier to find:
hey @OpenOrg-gg ! how's it going with the fixes?
But this is calculating the loss and adding it in right? The line is if the debt of the vault is more than the assets we have, there must be a loss. That loss must be the delta between the two values.
So it starts at 0 but we're adding _vaultDebt.sub(_totalAssets) if vaultDebt > totalAssets. Otherwise we keep it at 0?
I'm saying the code should instead just be:
_loss = _vaultDebt > _totalAssets ? _vaultDebt.sub(_totalAssets) : 0;
hey @OpenOrg-gg ! how's it going with the fixes?
I'm back on it, my fault, will stay on this until it's done :)
I'm not sure how I would structure that; but, I also think I disagree.
Stuck funds are extremely rare and usually only in a problem state, especially with a new protocol that hasn't been around as long as other lending markets like Compound.
I think at early stages it is most likely that stuck funds represent an exploit, or a breakdown of the protocol where the ability to return those assets is uncertain. I think they should be counted as lost until they can be returned in this case.
Otherwise the assets are stuck if they are not counted as a loss, a user will be pulling funds from other strategies in the vault, without us being sure if we will recoup those assets.
It feels like this is something that should be handled on a per protocol basis, based on what can cause stuck funds, and how uncommon it is?
For gen lender, we handle stuck funds as non-lossy: https://github.com/flashfish0x/yearnV2-generic-lender-strat/blob/f55c63ef3feaa03fb61e262ed4954db3e7f1cddc/contracts/Strategy.sol#L521
yes, it would pass on to other strategies, but I also don't really like the idea of passing on a loss to a user who happens to hit the lender in the queue if utilization is at 100%. it has happened multiple times that we get 100% utilization in lenders, or at the very least that yearn has more funds deposited into a lender than is liquid in the market itself.
In the situation where losses aren't assessed, and the user just gets back only free funds, that prevents users from taking the loss individually (or assessing it to the whole vault) but also allows yearn to step in if there is an exploit. Furthermore, assessing losses if stuck could mean that users don't actually get made whole because they exited with a loss, when we airdrop more funds to the strategy in case of an exploit.
this is going to be turned into a Genlender plugin
clone
function and make the name another init variable.if(!emergencyMode)
instead of comparing with == false
. balanceOfWant()
locally in a variable for the boolean expression and the for the deposit. Saves gas.withdrawSome(_amountNeeded)
?eToken.withdraw(Math.min(balanceOfUnderlyingToWant(), availableBalanceOnEuler()))
emergencyMode
makes sense. We already have emergencyExit
on strategies that you can use if you want to check whether this strategy is under an emergency situation._initializeThis
and the constructor should could _initializeThis
. The only one that should not be on the initializeThis
is the isOriginal
variable setting. You can do that directly on Line 112.public
and not external
? Is it intended to be used within the SC?strategistSMS
as treasury or who is going to keep the eul tokens. I think it's better to change this in the future and also eventually create a treasury for this exactly. @dudesahn do you share my opinion? or should be doing somehting else?If you declare something as an address, you don't need to bother re-casting it as an address. so on both L101 and L102 you can remove the address() portion and just leave the address itself
What is this address, as well as the one on L202? Would be good to have at least a comment explaining what they are. Also, similarly here, I don't think you need to cast these with address() and can just input them directly as args.
no need to set this to zero, will automatically be zero. can remove L206 completely and L100 can just be address public tradeFactory;
You already have a function for this, so estimatedTotalAssets()
should just
return balanceOfWant().add(balanceOfUnderlyingToWant());
and you can delete L217
https://github.com/OpenOrg-gg/yearn-euler/blob/f607abaf20955b678bcc63103cc25d0fd9e1ccbf/contracts/Strategy.sol#L219
this var doesn't appear to be used
_withdrawSome()
should just return the postBalance
, as withdraw()
on baseStrategy
expects liquidatePosition()
to return the total amount of assets freed
Probably good to add a comment here that calling this will result in losses on any funds that happen to be borrowed out that would then be realized later as profit if liquidity did return
This isn't used anywhere, can remove
This seems like a waste of gas, shouldn't estimatedTotalAssets()
stay the same from where you called it above?
Just to confirm, when is this value updated in the contract? Is it only when we interact with the contract, does it update when anyone interacts with the contract, or does it just increase on its own?
I think I mentioned this before, but I'm still unclear why you are doing _loss
plus what the real loss is. that _loss
that you're adding to should already be zero, so there's no reason to add to it, just assign it the value.
does this line do anything? appears to just be a view, which would be useless here
Description:
Commit (hash):
Tag:
Repo: https://github.com/OpenOrg-gg/yearn-euler
Scope: (List link to files)
Due Diligence: (attach link to due diligence document, see template here)
Additional References or Repo (Link to underlying protocols or relevant documents):
Deployed Contract (etherscan link):
Review Ongoing By:
Review Completed By: