Skip to content

V6 revised#8

Open
OpenOrg-gg wants to merge 4 commits intomasterfrom
v6-revised
Open

V6 revised#8
OpenOrg-gg wants to merge 4 commits intomasterfrom
v6-revised

Conversation

@OpenOrg-gg
Copy link
Copy Markdown
Owner

No description provided.

Copy link
Copy Markdown

@charlesndalton charlesndalton left a comment

Choose a reason for hiding this comment

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

Left some comments. Please feel free to reach me on TG @charlesndalton if you have any questions/disagreements. Also, Mickey tells me that you are new to yStrategies – welcome!


interface IDecimals {
function decimals() external view returns (uint8);
function decimals() external view returns (uint256);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Instead of introducing IDecimals, you can use IERC20Metadata. Imported with 'import {IERC20Metadata} from "@yearnvaults/contracts/yToken.sol";'

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Can't do this with the standard library, which brings the decimal in as uint8.

When we use the decimals in getting to converted base:

uint256 convertedBase = base.mul(10 ** IDecimals(address(want)).decimals()).div(sharePrice);

A uint8 would overflow and so it needed to be casted to a uint256.

return balanceOfWant();
}


Copy link
Copy Markdown

Choose a reason for hiding this comment

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

re: expTime in _sellRewards, since this is initiated from a contract and not an EOA I'm pretty sure you don't need to declare expTime and can just input 'now' into the function

uint256 public constant max = type(uint256).max;

//Base amount for floor $LOOKS token
uint256 private constant base = 1e18;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggest renaming this variable to something more descriptive (e.g., LOOKS_DUST)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Done:

base -> LOOKS_MIN

Comment on lines +123 to +128
event profitEvent(uint256 _amount);
event sharePriceEvent(uint256 _amount);
event amountEvent(uint256 _amount);
event sharesEvent(uint256 _amount);
event convertedBaseEvent(uint256 _amount);
event upperLimitEvent(uint256 _amount);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You've got some funny line justification here

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I see for the below events as well

event sharesEvent(uint256 _amount);
event convertedBaseEvent(uint256 _amount);
event upperLimitEvent(uint256 _amount);
function withdrawProfitOrFloor(uint profit) internal {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I feel the name 'withdrawProfitOrFloor' is not super intuitive–would suggest renaming

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Also, have you considered consolidating this logic and the liquidatePosition() logic (if it is different) in liquidatePosition() and calling that?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Also, have you considered consolidating this logic and the liquidatePosition() logic (if it is different) in liquidatePosition() and calling that?

Will need to evaluate that more. My hunch is that we do want these to be distinct assuming there are other times we'd want to call liquidatePosition() that doesn't come from the reporting?

looksRareContract.withdrawAll(false);

//We do a check to see if we have any WETH from the last rewards set that isn't converted.
uint256 wethCheck = IERC20(WETH).balanceOf(address(this));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

wethCheck -> wethBalance

//We do a check to see if we have any WETH from the last rewards set that isn't converted.
uint256 wethCheck = IERC20(WETH).balanceOf(address(this));

//If the WETH balance is non-zero we'll initiate a swap.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: "we'll initiate a swap" -> "we'll transfer it to the new strategy"

//check if tokens are approved as needed.
if(IERC20(LOOKSToken).allowance(address(this),LooksRareStaking) == 0){
IERC20(LOOKSToken).approve(LooksRareStaking, max);
if(LOOKSToken.allowance(address(this),LooksRareStaking) == 0){
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If this is a first time approval, why do you need to check allowance? Shouldn't it always be 0?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Yeah, this was a relic from a version where I had univ2 router as changable and this function recallable so we could switch between other AMMS.

Resolved this.


//We then withdraw with claim to get the full balance including the latest rewards
looksRareContract.withdrawAll(true);
//Full withdraw excluding rewards incase of reward errors.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Just curious, what are the reward errors?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

It's a MasterChef system, they internally calculate rewards based on their rewards curve, and when a user claims it, it mints it from the ERC20 contract it owns.

Those can have issues in three locations:

  1. If the ERC20 mint has a cap, the MasterChef doesn't check for that before assigning a user rewards. So if there was a 1M token cap, and 0.9M had been minted, but an additional 200k tokens were waiting in our pending rewards if we try and claim it would all fail.

  2. In the event that MasterChef loses minting rights over the token (such as if they migrate versions) the rewards claiming fails.

  3. If they change the reward curve after launch, pending rewards can down right break in the way they are calculated depending on last check in (underflow usually), so the claiming breaks.

Most team's realize these things and either modify MasterChef, or plan their rewards curve before hand and do not change it so it all aligns, but it is possible that you run into these issues.

@@ -332,7 +336,7 @@ event postWithdrawBalanceEvent(uint256 _amount);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm not sure but ySwaps may be required here, instead of selling from strat. WDYT @Micky?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Open to it, but the liquidity is pretty good, so unless this strategy gets quite large, I can't see the sells being worth a frontrun. But not as experienced with that part.

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