Skip to content

update yearn vault to v2#47

Merged
chudnov merged 41 commits into
masterfrom
yearn-vault-upgrade
Aug 3, 2021
Merged

update yearn vault to v2#47
chudnov merged 41 commits into
masterfrom
yearn-vault-upgrade

Conversation

@chudnov
Copy link
Copy Markdown
Contributor

@chudnov chudnov commented Jul 19, 2021

No description provided.

uint256 expiry;

// uninitialized state
if (closeParams.currentOption <= address(1)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I changed this recently, needs to be if (closeParams.currentOption == address(0)) {

import {RibbonVault} from "./base/RibbonVault.sol";
import {IRibbonThetaVault} from "../../interfaces/IRibbonThetaVault.sol";

contract RibbonDeltaYearnVault is RibbonVault, OptionsDeltaYearnVaultStorage {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since the Delta vaults don't deal with yvUSDC, why do we need to have a Yearn implementation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was thinking buying options whilst keeping the reserves in yvUSDC so your net loss every week is smaller. But I guess not worth.

address _oTokenFactory,
address _gammaController,
address _marginPool,
address _gnosisEasyAuction
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We're missing passing the Yearn registry

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

in v1, we had it in constructor because the asset parameter was there. but the asset parameter is now in initialize, so I pass it in there. yearnRegistry is only used once to get the collateral token, so I don't think it is necessary to pass it in constructor, hold it as a constant, and then reference it in initialize. Just pass it into initialize

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Understood, sounds good

}

if (vaultFee > 0) {
transferAsset(payable(feeRecipient), vaultFee);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Following this function here, just confirming that we're going to collect fees in yvUSDC?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it's fine to collect fees in yvUSDC btw, if it simplifies things

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I changed it to be yvUSDC

require(newOption != address(0), "!nextOption");

// Wrap entire `asset` balance to `collateralToken` balance
_wrapToYieldToken();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it possible to move this to the bottom of the function? We're following the check-effect-interaction pattern so we should do interactions that involve asset transfers last.

*/
function burnRemainingOTokens() external onlyOwner nonReentrant {
// Wrap entire `asset` balance to `collateralToken` balance
_wrapToYieldToken();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

returns (uint256 withdrawAmount)
{
function _withdrawYieldAndBaseToken(
address payable recipient,
Copy link
Copy Markdown
Contributor

@kenchangh kenchangh Jul 21, 2021

Choose a reason for hiding this comment

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

We don't need payable since it's converted under the hood

/*
Upgrades the vault to point to the latest yearn vault for the asset token
*/
function upgradeYearnVault() external onlyOwner {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this should be called in between commitAndClose() and rollToNextOption(). only time we have all the collateral back in the vault

Comment thread contracts/vaults/YearnVaults/base/RibbonVault.sol
GAMMA_CONTROLLER,
MARGIN_POOL,
newOption,
wdiv(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can try removing DSMath entirely as an import by copy pasting the wdiv/wmul functions into the contract, see if that helps with the size

import {ShareMath} from "../../libraries/ShareMath.sol";
import {RibbonVault} from "./base/RibbonVault.sol";

contract RibbonThetaYearnVault is RibbonVault, OptionsThetaYearnVaultStorage {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can remove OptionsThetaYearnVaultStorage since it's already inherited by RibbonVault?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

good catch. originally made sense because we had theta / delta vaults so they diverged in whats needed for storage, but we have deleted delta

Comment on lines +45 to +55
event NewOptionStrikeSelected(uint256 strikePrice, uint256 delta);

event PremiumDiscountSet(
uint256 premiumDiscount,
uint256 newPremiumDiscount
);

event AuctionDurationSet(
uint256 auctionDuration,
uint256 newAuctionDuration
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can remove these events imo

import {ShareMath} from "../../libraries/ShareMath.sol";
import {RibbonVault} from "./base/RibbonVault.sol";

contract RibbonThetaVault is RibbonVault, OptionsThetaVaultStorage {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we cannot do this because theta vaults inherit OptionsThetaVaultStorageV1 and delta vaults inherit OptionsDeltaVaultStorageV1.

both with different storage variables.

ribbon vault inherits OptionsVaultStorage which is the commonality between the two vaults

Comment on lines +90 to +83
uint256 performanceFee,
uint256 vaultFee,
uint256 round
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I must have missed this before, we should replace the vaultFee for managementFee

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I actually added managementFee as well.

vaultFee is how much we actually made that week which is worth passing in

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The dev can just do performanceFee + managementFee = vaultFee so it's redundant?

feeRecipient,
vaultFee
);
emit CollectVaultFees(performanceFee, vaultFee, vaultState.round);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Refer to https://github.com/ribbon-finance/ribbon-v2/pull/47/files#r676746116

emit CollectVaultFees(performanceFee, managementFee, vaultState.round);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

see above

@kenchangh kenchangh force-pushed the yearn-vault-upgrade branch from de0e7c2 to b811b96 Compare July 29, 2021 13:23
@chudnov chudnov force-pushed the yearn-vault-upgrade branch 2 times, most recently from 7b4d3f8 to 34757eb Compare July 30, 2021 16:58

before(async function () {
// Reset block
await network.provider.request({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there some way to avoid doing hardhat_reset? Calling reset breaks the test coverage tool.

Alternatively, we can use this solution to fork the state.

assert.isAtMost(receipt.gasUsed.toNumber(), 1045000);
// console.log("commitAndClose", receipt.gasUsed.toNumber());
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit missing newline

Comment on lines +94 to +98
premium = GnosisAuction.getOTokenPremium(
otokenAddress,
optionsPremiumPricer,
premiumDiscount
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Needs to account for the fact that the put contracts are collateralized with yvUSDC

(uint256 lockedBalance, uint256 newPricePerShare, uint256 mintShares) =
VaultLifecycleYearn.rollover(
totalSupply(),
totalBalance(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we're meant to pass in the collateralToken.balanceOf(address(this)) (yvUSDC balance) instead of totalBalance() (USDC balance)

This is likely why it's throwing off the calculation in VaultLifecycleYearn.createShort

@coveralls
Copy link
Copy Markdown

coveralls commented Aug 3, 2021

Pull Request Test Coverage Report for Build 1094642468

  • 0 of 384 (0.0%) changed or added relevant lines in 7 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-1.2%) to 1.608%

Changes Missing Coverage Covered Lines Changed/Added Lines %
contracts/vaults/BaseVaults/base/RibbonVault.sol 0 3 0.0%
contracts/vaults/BaseVaults/RibbonThetaVault.sol 0 4 0.0%
contracts/vaults/BaseVaults/RibbonDeltaVault.sol 0 5 0.0%
contracts/libraries/VaultLifecycle.sol 0 7 0.0%
contracts/vaults/YearnVaults/RibbonThetaYearnVault.sol 0 64 0.0%
contracts/vaults/YearnVaults/base/RibbonVault.sol 0 149 0.0%
contracts/libraries/VaultLifecycleYearn.sol 0 152 0.0%
Totals Coverage Status
Change from base Build 1078808900: -1.2%
Covered Lines: 15
Relevant Lines: 858

💛 - Coveralls

Comment thread test/RibbonThetaYearnVault.ts Outdated
gasLimits: {
depositWorstCase: 151608,
depositBestCase: 130594,
depositBestCase: 130681,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Follow up PR after this, let's gas golf the deposit flow for ThetaYearnVault

@chudnov chudnov merged commit ffc9fa2 into master Aug 3, 2021
@chudnov chudnov deleted the yearn-vault-upgrade branch August 3, 2021 16:53
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.

3 participants