Open kitty-the-kat opened 1 year ago
challenged - informational or low acknowledged - no fix needed, if running multiple strategies (which is the recommended approach) the harvest can be staggered in a way so as to minimize the 0 downtime Reasoning - MIN_REPORT_DELAY does not guarantee profit for the strategy. We can imagine a situation where the strategy harvest is in synch with the release factor, but the locked profit doesn't change or is less than the 2% that the Senior tranche is taking from the junior tranche - the only things that would guarantee that lockedProfit wouldn't return 0 is to have profitable strategies :D
I think the recommendation section could have been improved. But since you might have better ideas in that department, I'll elaborate on the issue I see and you can tell me whether this is a problem or not. If there is a withdrawal fee in the process to disincentivize short term deposits then this may be a non-issue:
_calculateLockedProfit()
uses a 24 hour intervalreleaseTime
to release profits to the vault. In contrast, thelockedProfit
amount is only updated whenreport()
is called by the strategy which has aMIN_REPORT_DELAY
value of 48 hours.Technical Details
_calculateLockedProfit()
is designed to slowly release profits to the GVault depositors. If thereleaseTime
is surpassed, which is 24 hours, it returns zero, which means no profit is locked. ThelockedProfit
value is updated whenreport()
in GVault is called by a strategy'srunHarvest()
. ConvexStrategy'scanHarvest()
, which indicates when a keeper can callrunHarvest()
, has a constantMIN_REPORT_DELAY
value of 48 hours. This means that ifMIN_REPORT_DELAY
is the determining factor for when a harvest happens,_calculateLockedProfit()
will return zero for roughly half of that minimum time period. During the time that_calculateLockedProfit()
returns zero, the profit calculation in PnLFixedRate oftotalValue - lastTotal
will return zero. This will causes the Senior Tranche to take value from the Junior Tranche to pay the fixed yield of the Senior Tranche.An example of how this could be leveraged to cause a loss for Junior Tranche holders:
report()
is called by a strategy, so the assets may not maximize their yield for some time_calculateLockedProfit()
is returning zero. This means beforereport()
will not have been called to deposit the loose 3CRV in the GVault to maximize yield, yet the depositor claims their fixed yield from the Senior Tranche at the cost of Junior Tranche depositors, who don't reap the full benefits of the 3CRV deposit into the GVault.If the above actions are performed frequently with large amounts of capital, say twice a week, the Junior Tranche may be less appealing for depositors. This is because the Junior Tranche is willing to pay the Senior Tranche the borrowing cost for leverage, but this cost makes more sense if the Junior Tranche is able to use the 3CRV in the strategy and not when it is sitting idle in the GVault. This scenario would get worse if the tranche had a large utilization ratio, say 10x, because the fee paid to the Senior Tranche would be larger. The flip side of this is that Junior Tranche depositors would be incentivized to withdraw their deposits during the time when
_calculateLockedProfit()
returns zero for the same reason.Impact
Medium. Many withdrawals from the Senior Tranche may extract substantial value from the Junior Tranche when
_calculateLockedProfit()
returns zero.Recommendation
Consider requiring strategies to use the same
MIN_REPORT_DELAY
value as the GVault'sreleaseTime
. Other redesigns should be considered as well to minimize the time when_calculateLockedProfit()
returns zero.