# Boosties Source: https://docs.cove.finance/ecosystem/boosties/boosties The first dedicated liquid locker and staking platform for Yearn, built using Yearn V3 Boosties Light Boosties Dark ## Boosties Boosties is a liquid locker and staking platform that allows users to efficiently benefit from Yearn's [dYFI](https://docs.yearn.finance/getting-started/products/veyfi#dyfi) emissions on their vault tokens. Boosties is built using Yearn V3 strategies to synergize with the Yearn ecosystem. dYFI is a token introduced as part of Yearn's veYFI tokenomics program. It is an ERC-20 token that allows its holder to buy back YFI at a discount (currently \~84.65%). dYFI is distributed to users who stake their Yearn vault positions. Hero Light Hero Dark ### Problem Yearn requires users to provide both **veYFI** (vote escrowed **YFI**) and vault tokens in proportion to earn maximum boosted **dYFI** yield on their positions. Users that do not balance their positions suffer from earning suboptimal **dYFI** emissions. ### Solution **Boosties** allows users to take full advantage of Yearn’s **dYFI** emissions through a protocol owned **veYFI** boost. This is done without requiring individuals to hold both **veYFI** and gauge tokens. ## Launch Parameters ### Guarded launch [Guarded launches](https://medium.com/electric-capital/derisking-defi-guarded-launches-2600ce730e0a) are a risk management approach for deploying new DeFi products that intentionally limit the functionality of a system using configurable rules and thresholds. This allows users to interact with the product in a limited, low-stakes environment initially. As confidence in the system grows over time, governance processes can relax the risk controls to allow the system to scale up safely. Boosties is initially launching with a TVL cap of \$50K per vault, which will be increased over time. ### Fees A 15% performance fee is charged on harvests: * 5% to the protocol treasury * 5% to coveYFI stakers * 5% to buy YFI and perma-lock it as coveYFI Additionally, a 5% performance fee is charged on early exit (YFI) and boost forfeit (dYFI) rewards for the protocol treasury. Gauntlet has developed a model to optimize Cove's fee structure, so these values will change in the future as the model output is incorporated into the protocol. The maximum treasury fee is capped at 20%. # coveYFI Source: https://docs.cove.finance/ecosystem/boosties/coveyfi A liquid locker for YFI coveYFI Light coveYFI Dark **coveYFI** is Cove’s liquid locker for **YFI**. **YFI** deposited into Cove is perpetually locked for **veYFI**, thus increasing the protocol's ownership of **veYFI** and Yearn gauge voting power. coveYFI Explainer coveYFI stakers receive yield from: * 95% of early exit rewards * 95% of boost forfeit rewards * 5% performance fee on harvests * \$COVE liquidity mining ### **What is a Liquid Locker?** A Liquid Locker is an innovative financial instrument embodied in a smart contract designed for the decentralized finance (DeFi) ecosystem. It enables participants to obtain and trade liquid tokens—such as **coveYFI** in this context—that represent ownership of locked governance tokens, specifically **veYFI**, without directly locking their **YFI** tokens. ### Key Features and Benefits * **Liquidity Preservation**: Unlike traditional staking mechanisms where locking governance tokens reduces market liquidity, Liquid Lockers allow users to maintain liquidity. Participants can trade their **coveYFI** tokens, allowing users to exit positions if desired. * **Enhanced Accessibility to Protocol Incentives**: Users benefit from protocol emissions and other incentives associated with holding governance tokens (**veYFI**) without the need to lock their assets for extended periods. This system democratizes access to yield-generating opportunities within the protocol, such as those offered by Yearn. * **Risk Mitigation**: By facilitating the trade of **coveYFI**, users can mitigate the risk associated with the volatility of the underlying **YFI** tokens. They gain the flexibility to enter and exit positions according to market conditions, without being tied to lock-up periods typically required to participate in governance or to earn protocol emissions. This mechanism ensures that while the governance tokens are locked and contributing to the protocol's security and decision-making processes, users retain the flexibility and liquidity. ### coveYFI/YFI Curve Pool A coveYFI/YFI Curve pool has been created [here](https://www.curve.finance/dex/ethereum/pools/factory-stable-ng-152/deposit/). Liquidity will be incentivized in future epochs. # dYFI Redeemer Source: https://docs.cove.finance/ecosystem/boosties/dyfi-redeemer Automatically redeem dYFI for YFI without holding ETH dYFI Redeemer Light dYFI Redeemer Dark ## dYFI Redeemer Boosties offers a special public good mechanism that allows users to claim **YFI** directly from their **dYFI** without needing **ETH**. The redeemer contract just needs to be approved once for users to earn **YFI** from their **dYFI** earnings. Using Yearn’s Redemption contract and by flashloaning **ETH**, users can more effectively acquire **YFI**. This process occurs asynchronously and is also gas-free for users not calling the redeemer contract. When a user calls the redeemer contract it claims **dYFI→YFI** and sends **YFI** to all users that have already approved the redeemer contract. Anyone can call this contract as it is permissionless. Any extra ETH that is returned in excess of the minimum amount is sent to the caller to incentivize automation. Users can opt-out of the redemptions by revoking the approved contract from their respective address. To make things easier for users, redemptions will be processed by keepers periodically. # The 4626 Alliance Source: https://docs.cove.finance/ecosystem/partners/4626-alliance Supporting the development and deployment of ERC-4626 vaults 4626 Alliance Light 4626 Alliance Dark ## Who is the 4626 Alliance? [The 4626 Alliance](https://erc4626.info/) is a group of leading protocols and applications that share the mission of supporting the development and deployment of `ERC-4626` vaults. `ERC-4626` drastically simplifies the process of building cool and useful applications by decreasing the complexity of integration while improving UX and security. ### How is Cove involved with the 4626 Alliance? Cove is a proud member protocol of the 4626 Alliance! # Bazaar Source: https://docs.cove.finance/ecosystem/partners/bazaar Empowering transparent, community-driven launches for all Bazaar Light Bazaar Dark ## Who is Bazaar? Bazaar is a decentralized, chain-agnostic launchpad providing crypto-natives with a fair, community-centric approach to fundraising. Bazaar offers the most competitive fee structure for both users and projects, while incentivizing high-quality launches and community-led curation. The protocol supports liquidity bootstrapping pools, with support for additional launch mechanisms such as uncapped and capped batch auctions coming soon. Bazaar enables seamless, one-click cross-chain swaps across Ethereum and supported Layer 2 networks, effectively abstracting away the convoluted process of navigating between networks for the end user, while making it easier for L2 protocols to bootstrap natively. The future is undoubtedly multi-chain, and projects launching on Bazaar can tap into universal liquidity across Ethereum, Optimism, Arbitrum, Base, Polygon, ZkSync Era, and additional networks in the near future. Performant cross-chain UX is the end-game for all crypto-native applications, and Bazaar is bringing this vision to market today. ### How is Bazaar involved with Cove? An uncapped batch auction was held on April 22, 2024 on Bazaar for 0.95% of the \$COVE supply in exchange for ETH to help bootstrap protocol owned liquidity. Learn more about the launchpad [here](/ecosystem/token/launchpad). # Gauntlet Source: https://docs.cove.finance/ecosystem/partners/gauntlet The premier DeFi-native economic research firm Gauntlet Light Gauntlet Dark ## Who is Gauntlet? [Gauntlet](https://www.gauntlet.xyz/) generates off-chain intelligence to drive onchain efficiency, delivering DeFi’s premier quantitative analysis to leading protocols. Our research and solutions help the industry to navigate difficult decisions, identify areas for growth, and elevate DeFi as a whole. Gauntlet uses advanced statistical techniques for quantitative analysis, modeling, and optimization. Our methods are applicable to optimizing validator efficiency, incentivizing developer participation, accelerating ecosystem utility, and mitigating gaming of incentive programs. ### How is Gauntlet involved with Cove? Gauntlet is optimizing the protocol’s rebalancing mechanism, YFI gauge system, and other parameters. # Ritual Source: https://docs.cove.finance/ecosystem/partners/ritual The network for open AI infrastructure Ritual Light Ritual Dark ## Who is Ritual? [Ritual](https://ritual.net/) is an open, sovereign execution layer for AI. Seamlessly integrate AI into your app or protocol on any chain, enabling you to fine-tune, monetize, and perform inference on models with cryptographic schemes. With Ritual, the vision is for developers to be able to build fully transparent DeFi, self-improving blockchains, autonomous agents, generated content, and more. ### How is Ritual involved with Cove? Cove is collaborating with Ritual on AI-enabled strategies. Stay tuned for more updates soon! # Storm Labs Source: https://docs.cove.finance/ecosystem/partners/storm-labs More about the early core contributors Storm Labs Light Storm Labs Dark ## Who is Storm Labs? [Storm Labs](https://storm-labs.xyz/) is a software development studio that builds infrastructure for the next financial generation. The Storm Labs team is developing the initial version of the Cove Protocol. The company recently announced a [\$3M pre-seed fundraising round](https://twitter.com/cove_fi/status/1777723825288831384) led by [Electric Capital](https://electriccapital.com/), with participation from [Accomplice](https://accomplice.co/), [Robot Ventures](https://robvc.com/), [Daedalus](https://www.daedalus.gg/), and other notable angel investors: Storm Labs Investors ### Team The team is comprised of DeFi veterans, led by [devops199fan](https://twitter.com/devops199fan), an early YFI contributor, founding partner at [eGirl Capital](https://www.egirlcapital.com/), and previous founder of Saddle, the first open-source StableSwap with \$2.2B+ in volume. Storm Labs History Learn more about the team: The official Storm Labs website. ### Advisors * [Joey Santoro](https://twitter.com/joey__santoro) * Founder of [Fei Protocol](https://fei.money/) & author of ERC-4626, the tokenized vault standard. * [Tarun Chitra](https://twitter.com/tarunchitra) * Founder & CEO of [Gauntlet](https://gauntlet.xyz/), the premier DeFi-native economic research firm. # Cove Protocol Source: https://docs.cove.finance/ecosystem/protocol/cove-protocol The one-stop platform for earning onchain Cove Protocol Light Cove Protocol Dark ### What is the Cove Protocol? Cove pairs off-chain intelligence with on-chain automation to deliver curated 1-click DeFi vaults that earn higher, safer yield. * A simplified way to earn onchain that hides the complexity of best-in-class management. * Easy access to sophisticated strategies run by experts like [Gauntlet](https://www.gauntlet.xyz/). * Earns \$1B+ in additional profit for LPs by eliminating [loss-versus-rebalancing (LVR)](https://a16zcrypto.com/posts/article/lvr-quantifying-the-cost-of-providing-liquidity-to-automated-market-makers/) using [Programmatic Orders](https://docs.cow.fi/cow-protocol/concepts/order-types/programmatic-orders). * Better execution when internal trades are matched offchain by Cove's solver and settled without leaking value, like ring trades in [batch auctions](https://docs.cow.fi/cow-protocol/concepts/how-it-works/coincidence-of-wants). ### How does it work? Cove aggregates deposits and rebalances periodically using [Programmatic Orders](https://docs.cow.fi/cow-protocol/concepts/order-types/programmatic-orders). When rebalancing, strategies may have a [coincidence of wants](https://en.wikipedia.org/wiki/Coincidence_of_wants) (CoW) like ring trades in [CoW Swap's batch auctions](https://docs.cow.fi/overview/coincidence-of-wants). Cove maximizes the volume of CoWs using linear programming. This is done by considering the current/target protocol level allocations off-chain. When there are matches, trades occur without losing value from price impact, slippage, fees, or MEV. Any external trades are routed through CoW Swap (which now supports programmatic orders including TWAP via their [Programmatic Order Framework](https://blog.cow.fi/introducing-the-programmatic-order-framework-from-cow-protocol-088a14cb0375)) to ensure the best execution and capture positive slippage. Cove uses the ERC-4626 tokenized vault standard and [ERC-7540 Asynchronous ERC-4626 Tokenized Vaults](https://eips.ethereum.org/EIPS/eip-7540) to combine diverse yield sources. The `coveUSD` vault, for instance, takes `USDC` deposits and allocates them across a diversified portfolio of high-quality, yield-bearing stablecoins to generate returns. ### Deposits & Withdrawals Cove provides flexible, asynchronous options for moving funds in and out of the `coveUSD` vault. This model is a core feature designed to protect LPs from value leakage by batching transactions. Depositing into `coveUSD` is a two-step asynchronous process designed to align with the protocol's rebalancing cycle. You deposit `USDC` into the protocol. Your funds are securely held and queued for inclusion in the next rebalancing event. After the rebalance is complete (typically within 24 hours), you can claim your `coveUSD` tokens, which represent your share in the vault. **Automated Claiming:** This step can be handled automatically for you by our non-custodial off-chain infrastructure. You can also manually claim your tokens at any time. You have two options for withdrawals, allowing you to choose between receiving `USDC` or a mix of the vault's underlying assets. #### Asynchronous USDC Withdrawal This is the standard withdrawal method that returns `USDC` to you. You submit a request to redeem your `coveUSD` for `USDC`. Your request is queued for the next rebalancing event. After the rebalance, the protocol processes your request, and your `USDC` becomes claimable. This process typically takes around 24 hours. **Automated Claiming:** This step can be handled automatically for you by our non-custodial off-chain infrastructure. You can also manually claim your tokens at any time. #### Synchronous Pro-Rata Redemption For immediate access to your funds, you can redeem your `coveUSD` for a proportional share of all the assets currently held within the vault. For example, if the vault holds assets like `sUSDe` (Ethena) and `sfrxUSD` (Frax), a pro-rata redemption would instantly give you a mix of these assets. This option is available at any time except during a rebalance. The Cove Protocol pauses operations for a daily rebalancing window that typically lasts 15 minutes. During this period, deposits, claims, and withdrawals are temporarily unavailable. The rebalancing process may retry up to two times if needed, potentially extending this window up to 45 minutes. ### What makes Cove unique? Traditional AMMs are not well suited for portfolio or index construction because they suffer from [loss-versus-rebalancing (LVR)](https://a16zcrypto.com/posts/article/lvr-quantifying-the-cost-of-providing-liquidity-to-automated-market-makers/). This is because of [toxic order flow](https://insights.deribit.com/market-research/toxic-flow-its-sources-and-counter-strategies/): all trades execute at worse-than-market prices. Cove proposes an innovative new approach that eliminates LVR and offers the best onchain execution. Internal trades avoid slippage, MEV, price impact, and external trading fees. External trades route through CoW Swap which also protects from MEV and captures positive slippage. **Key Differentiators** 1. Expert strategies - earn best-in-class yields optimized by curators like [Gauntlet](https://www.gauntlet.xyz/). 2. Automation - no more manual management or rebalancing of positions to chase yield. Cove is the next generation of yield farming and portfolio management. 3. Earn the most yield - Cove protects you from loss-versus-rebalancing and common DeFi pitfalls like slippage, MEV, price impact, and external trading fees. 4. Fully collateralized - redeemable for a pro-rata share of underlying assets synchronously, or in the base asset asynchronously. 5. Less risk - No exposure to cross-chain or duration risk (outside of the rebalancing period). # coveUSD Source: https://docs.cove.finance/ecosystem/protocol/coveusd Cove's flagship vault delivering institutional-grade USD yield ## Overview coveUSD is Cove's flagship vault that delivers institutional-grade USD yield through automated capital allocation. By pairing off-chain intelligence with on-chain automation, coveUSD seeks to establish the benchmark rate for safe, blue-chip USD yield on Ethereum. ### Key Features Routes deposits through off-chain Silverback bots and Gauntlet's institutional-grade risk models. Automatically reallocates capital across top-tier strategies to maximize risk-adjusted returns. Achieved net APYs up to 8.08% over the past three months. Future active management secured behind a timelock for transparent governance. ## How It Works ### Strategy Selection coveUSD dynamically allocates capital across a curated selection of blue-chip USD yield strategies: Synthetic dollar protocol offering sustainable yield. Frax's staked USD stablecoin. Multi-protocol yield optimization (Euler/Fluid). Maker/Spark yield vault. ### Intelligent Rebalancing The vault employs sophisticated off-chain intelligence to optimize allocations. Gauntlet's models continuously assess risk/reward profiles across strategies. Silverback bots monitor yield opportunities 24/7. Rebalancing occurs through Programmatic Orders to minimize costs. ## Deposits and Withdrawals coveUSD offers flexible options for entering and exiting positions. ### Deposits You can deposit USDC into the protocol at any time. Your deposit is processed during the next rebalancing cycle. Your coveUSD tokens become available to claim after the rebalancing event completes. **Automated Claiming:** This step is handled automatically for you by our non-custodial off-chain bots. You can also claim your tokens manually if you prefer. ### Withdrawals You have two options for withdrawing your funds from the vault. Redeem your `coveUSD` for a proportional share of the vault's underlying assets. This option is available at any time, except during rebalancing windows. You will instantly receive a basket of the vault's current holdings (e.g., sUSDe, sfrxUSD, etc.). You can request to withdraw your entire position in USDC. The request is processed during the subsequent rebalancing event, which typically occurs within 24 hours. Your USDC becomes claimable after the rebalancing is complete. **Automated Claiming:** This step is handled automatically for you by our non-custodial off-chain bots. You can also claim your tokens manually if you prefer. ## Performance coveUSD has demonstrated strong risk-adjusted returns: * **Historical APY**: Up to 8.08% net over the past three months * **Consistent Yield**: Automated rebalancing captures opportunities across market conditions * **Cost Efficiency**: CoW Swap integration minimize execution costs ## Security * **Audited**: Smart contracts audited by Trail of Bits, Pashov Audit Group, Zellic, Quantstamp, and yAudit * **Timelock**: Active management changes subject to governance timelock * **Fully Collateralized**: Always backed 1:1 by underlying assets * **Transparent**: All allocations and rebalancing visible on-chain # Governance Source: https://docs.cove.finance/ecosystem/token/governance Details about protocol governance Governance Light Governance Dark ## Governance At launch, governance will be controlled as follows: * \$COVE token holders via Snapshot * Enabling transfers for \$COVE * Fee switches and settings * Funds in the DAO treasury * Community multisig with input from Gauntlet and core contributors * All other operational admin key functionality (parameters, etc.) Fully onchain governance (e.g. [Llama](https://llama.xyz/), [OpenZeppelin Governor](https://docs.tally.xyz/education/governance-frameworks/openzeppelin-governor), SafeSnap [Reality](https://docs.snapshot.org/user-guides/plugins/safesnap-reality) / [oSnap](https://docs.snapshot.org/user-guides/plugins/safesnap-osnap)) will be launched prior to \$COVE being unpaused, at which point the community multisig will be sunset and the protocol will be completely controlled by token holders. ### Process \$COVE token holders can vote on proposals. Initially, the proposals will be on [Snapshot](https://vote.cove.finance/), which the community multisig will then enact. [Discourse](https://gov.cove.finance/) will be the platform for discussion of the proposals. Governance Process ### Community Multisig The community multisig is a 3/7 [Safe](https://safe.global/) which can be found [here](https://app.safe.global/home?safe=eth:0x7Bd578354b0B2f02E656f1bDC0e41a80f860534b). The signers are: | Name | Affiliation | Address | | ---------------------------------------------------- | ---------------------------------- | -------------------------------------------- | | [scoopy trooples](https://twitter.com/scupytrooples) | [Alchemix](https://alchemix.fi/) | `0xf872703F1C8f93fA186869Bac83BAC5A0c87C3c8` | | [DeFi Dude](https://twitter.com/defidude) | [Builda](https://builda.dev/) | `dude.eth` | | [0xtoucan](https://twitter.com/0xtoucan) | [The Graph](https://thegraph.com/) | `0x88cD106fd4002921D71358455ff95c1Af8b951B7` | | [lowpolyduck](https://twitter.com/lowpolyduck) | [Mezo](https://mezo.org/) | `lowpolyduck.eth` | | [Facu](https://twitter.com/saltyfacu) | [Yearn](https://yearn.fi/) | `0x114fC13bDf5FEFd6D83Ea17d7B4ce7447712F08c` | | [corn](https://twitter.com/omgcorn) | [Yearn](https://yearn.fi/) | `0xF53D1fB2EeD22Cf1E8f7E90Da7f1CAe88344065F` | | [Schlag](https://twitter.com/Schlagonia) | [Yearn](https://yearn.fi/) | `0xB865AAf1f9f60630934739595f183C4900f65ed9` | ### Yearn Governance The community multisig will vote in line with recommendations from Gauntlet. Gauntlet has developed models to optimize the protocol's gauge votes and fees. Snapshot Explainer # Token Information Source: https://docs.cove.finance/ecosystem/token/info $COVE — A non-transferable protocol governance token $COVE Light $COVE Dark ## Token Overview \$COVE is the protocol's governance token. It is currently non-transferable for a minimum of 6 months, after which the DAO can vote to enable transfers. After 18 months, anyone may enable transfers. At the moment, \$COVE is non-transferable and only used for voting in protocol governance. In the future, we expect governance proposals to enable transfers and add additional utility and tokenomics.
Token Distribution Light Token Distribution Dark ## Initial Distribution The initial supply of 1 billion \$COVE has been minted at genesis and will become available over the course of 3 years. The initial distribution is as follows: * **55% to Community** * **0.5%** to Community multisig signers, with 1-year linear vesting. * **0.95%** to the Bazaar launchpad auction, with 1-year linear vesting. * **8%** for 1st-year liquidity mining incentives. At the community multisig's discretion, unused tokens will be returned to the treasury after 1 year. * **30.55%** to the Community treasury, with 3-year linear vesting. * **15%** to the Foundation. * **45% to current and future team, investors, and advisors** * Investors have a 2-year linear vesting period. * Team and advisors have a 3-year linear vesting period. ## Token Specification The source code for the token can be found on Github [here](https://github.com/Storm-Labs-Inc/cove-contracts-boosties/blob/master/src/governance/CoveToken.sol) or on Etherscan [here](https://etherscan.io/address/0x32fb7D6E0cBEb9433772689aA4647828Cc7cbBA8#code). * Name: Cove DAO * Ticker: COVE * Initial supply: 1B * Modifiers * Ownable/governance * Permit * Pausable * Non-transferable for 18 months (anyone can unlock after) * DAO can vote to enable transfers after 6 months * Additional functionality * Rescue function for ETH/ERC20s * Transfer allowlist * Max 6% per year starting after 3 years ([ARB style inflation](https://docs.arbitrum.foundation/airdrop-eligibility-distribution)) # Launchpad on Bazaar Source: https://docs.cove.finance/ecosystem/token/launchpad Uncapped batch auction for $COVE Launchpad Light Launchpad Dark ## Bazaar Launchpad Bazaar is a decentralized, chain-agnostic launchpad providing crypto-natives with a fair, community-centric approach to fundraising. An uncapped batch auction was held on April 22nd, 2024 on Bazaar for 0.95% of the \$COVE supply in exchange for ETH to help bootstrap protocol owned liquidity. In an uncapped batch auction, participants receive a proportional share of tokens based on their contribution relative to the total amount pledged. This ensures fairness for all users, though the exact proportion is uncertain beforehand. Funds were used to purchase YFI and seed the [coveYFI/YFI Curve pool](https://www.curve.finance/dex/ethereum/pools/factory-stable-ng-152/deposit/) as protocol owned liquidity (PoL). The purchase was facilitated by the [community multisig](/ecosystem/token/governance#community-multisig). At the moment, \$COVE is non-transferable and only used for voting in protocol governance. In the future, we expect governance proposals to enable transfers and add additional utility and tokenomics. For more details on \$COVE, please refer to the [token documentation](/ecosystem/token/info). ### Auction parameters | Parameter | Value | | ---------------------- | ------------------------ | | Auction type | Uncapped batch auction | | Auction start date | April 22nd, 2024 | | Auction duration | 3 days | | % of token supply sold | 0.95% | | Reserve implied FDV | \$30MM | | Vesting | 1y linear (voting power) | # Liquidity Mining Source: https://docs.cove.finance/ecosystem/token/liquidity-mining Provide liquidity and earn incentives $COVE Light $COVE Dark # Program Details Cove's liquidity mining program is divided into seasons, each with specific goals and reward structures. 8% of the token supply is planned to be distributed during the first year of liquidity mining. Epochs will have different objectives and emissions. ## Season 2 (Cove + coveUSD) We're currently on Season 2 of liquidity mining which is for the main [Cove Protocol](/ecosystem/protocol/cove-protocol) and currently only distributed to [coveUSD](/ecosystem/protocol/coveusd). ### Epoch 0 Epoch 0 will be four weeks long and is focused on bootstrapping coveUSD. Epoch 0 will begin around Friday May 30th at 11 PM EST (May 31st 4 AM UTC) and the emissions are as follows: | Target | Emissions (4 weeks) | | --------- | ------------------- | | \$coveUSD | 730,800 \$COVE | ## Season 1 (Boosties) Season 1 liquidity mining for [Boosties](/ecosystem/boosties/boosties) ended with Epoch 8. During this season, [\$COVE](/ecosystem/token/info) was distributed to users who staked: * \$coveYFI * Cove Boosties LP tokens * coveYFI/YFI Curve LP tokens ### Epoch 0 Epoch 0 will be three weeks long and is focused on bootstrapping the protocol's \$coveYFI supply. Epoch 0 will begin around Friday April 12th at 11 PM EST (April 13th 4 AM UTC) and the emissions are as follows: | Target | Emissions (3 weeks) | | ----------------------- | ---------------------- | | \$coveYFI | 3,500,000 \$COVE | | Cove Boosties LP tokens | 1,000,000 \$COVE total | ### Epoch 1 Epoch 1 will be one month long and is focused on bootstrapping the protocol's \$coveYFI supply and new V3 vault TVL. Epoch 1 will begin around Saturday May 4th at 12 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------------- | -------------------- | | \$coveYFI | 3,500,000 \$COVE | | Cove Boosties V2 LP tokens | 750,000 \$COVE total | | Cove Boosties V3 LP tokens | 750,000 \$COVE total | ### Epoch 2 Epoch 2 will be one month long and continues to focus on bootstrapping the protocol's \$coveYFI supply and new V3 vault TVL. Epoch 2 will begin around Thursday June 6th at 12 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------------- | -------------------- | | \$coveYFI | 2,800,000 \$COVE | | Cove Boosties V2 LP tokens | 600,000 \$COVE total | | Cove Boosties V3 LP tokens | 600,000 \$COVE total | ### Epoch 3 Epoch 3 will be one month long and is focused on growing the new coveYFI/YFI Cove vault. Epoch 3 will begin around Tuesday July 23rd at 4 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------- | ------------------- | | \$coveYFI | 1,600,000 \$COVE | | LP Yearn PRISMA (v2) | 100,000 \$COVE | | WETH (v3) | 100,000 \$COVE | | LP Yearn CRV (v2) | 100,000 \$COVE | | Curve dYFIETH-f (v2) | 100,000 \$COVE | | Curve YFI-ETH (v2) | 150,000 \$COVE | | Curve yEth (v2) | 150,000 \$COVE | | USDC (v3) | 500,000 \$COVE | | DAI (v3) | 600,000 \$COVE | | coveYFI/YFI | 600,000 \$COVE | ### Epoch 4 Epoch 4 will be one month long and is focused on growing the 3 newly launched Cove vaults (DAI-2, crvUSD-2, WETH-2). Epoch 4 will begin around Tuesday August 24th at 4 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------- | ------------------- | | \$coveYFI | 850,000 \$COVE | | LP Yearn PRISMA (v2) | 50,000 \$COVE | | WETH (v3) | 100,000 \$COVE | | LP Yearn CRV (v2) | 350,000 \$COVE | | Curve dYFIETH-f (v2) | 100,000 \$COVE | | Curve YFI-ETH (v2) | 150,000 \$COVE | | Curve yEth (v2) | 150,000 \$COVE | | USDC (v3) | 550,000 \$COVE | | DAI (v3) | 400,000 \$COVE | | coveYFI/YFI | 200,000 \$COVE | | DAI-2 | 200,000 \$COVE | | crvUSD-2 | 200,000 \$COVE | | WETH-2 | 200,000 \$COVE | ### Epoch 5 Epoch 5 will be two months long and is focused on growing newer Cove vaults. Epoch 5 will begin around Monday October 14th at 1 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------- | ------------------- | | \$coveYFI | 600,000 \$COVE | | LP Yearn PRISMA (v2) | 50,000 \$COVE | | WETH (v3) | 100,000 \$COVE | | LP Yearn CRV (v2) | 300,000 \$COVE | | Curve dYFIETH-f (v2) | 150,000 \$COVE | | Curve YFI-ETH (v2) | 100,000 \$COVE | | Curve yEth (v2) | 50,000 \$COVE | | USDC (v3) | 500,000 \$COVE | | DAI (v3) | 150,000 \$COVE | | coveYFI/YFI | 100,000 \$COVE | | DAI-2 | 200,000 \$COVE | | crvUSD-2 | 50,000 \$COVE | | WETH-2 | 50,000 \$COVE | ### Epoch 6 Epoch 6 will be two months long and is focused on rewarding existing LPs. Epoch 6 will begin around Monday December 9th at 1 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------- | ------------------- | | \$coveYFI | 1,350,000 \$COVE | | LP Yearn PRISMA (v2) | 25,000 \$COVE | | WETH (v3) | 50,000 \$COVE | | LP Yearn CRV (v2) | 120,000 \$COVE | | Curve dYFIETH-f (v2) | 60,000 \$COVE | | Curve YFI-ETH (v2) | 50,000 \$COVE | | Curve yEth (v2) | 25,000 \$COVE | | USDC (v3) | 100,000 \$COVE | | DAI (v3) | 75,000 \$COVE | | coveYFI/YFI | 75,000 \$COVE | | DAI-2 | 10,000 \$COVE | | crvUSD-2 | 25,000 \$COVE | | WETH-2 | 35,000 \$COVE | ### Epoch 7 Epoch 7 will be two months long and is focused on rewarding existing LPs. Epoch 7 will begin around Monday February 3rd at 1 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------- | ------------------- | | \$coveYFI | 1,350,000 \$COVE | | LP Yearn PRISMA (v2) | 25,000 \$COVE | | WETH (v3) | 50,000 \$COVE | | LP Yearn CRV (v2) | 120,000 \$COVE | | Curve dYFIETH-f (v2) | 60,000 \$COVE | | Curve YFI-ETH (v2) | 50,000 \$COVE | | Curve yEth (v2) | 25,000 \$COVE | | USDC (v3) | 100,000 \$COVE | | DAI (v3) | 75,000 \$COVE | | coveYFI/YFI | 75,000 \$COVE | | DAI-2 | 10,000 \$COVE | | crvUSD-2 | 25,000 \$COVE | | WETH-2 | 35,000 \$COVE | ### Epoch 8 Epoch 8 will be two months long and is focused on rewarding existing LPs and bootstrapping the new USDS vault. Epoch 8 will begin around Thursday April 3rd at 1 PM EST and the emissions are as follows: | Target | Emissions (1 month) | | -------------------- | ------------------- | | \$coveYFI | 1,300,000 \$COVE | | LP Yearn PRISMA (v2) | 25,000 \$COVE | | WETH (v3) | 50,000 \$COVE | | LP Yearn CRV (v2) | 120,000 \$COVE | | Curve dYFIETH-f (v2) | 60,000 \$COVE | | Curve YFI-ETH (v2) | 50,000 \$COVE | | Curve yEth (v2) | 25,000 \$COVE | | USDC (v3) | 100,000 \$COVE | | DAI (v3) | 75,000 \$COVE | | coveYFI/YFI | 75,000 \$COVE | | DAI-2 | 10,000 \$COVE | | crvUSD-2 | 25,000 \$COVE | | WETH-2 | 35,000 \$COVE | | USDS | 50,000 \$COVE | # Using Boosties Source: https://docs.cove.finance/how-to/boosties How-to guides for using Boosties ## Using Boosties ### Depositing Depositing to a Boosties vault is easy. First, you'll need to deposit into the Yearn vault linked at the top of the description and then stake in [the corresponding gauge](https://veyfi.yearn.fi/). Select the respective vault for your tokens and click `Deposit`. Sign the approval to allow Boosties to use your tokens. Submit a final transaction to deposit tokens. The boost from protocol owned **veYFI** is immediately applied to users’ deposits. Users earn **COVE** tokens from their deposits as well once liquidity mining begins. ### Withdrawing Withdrawing your deposits is a breeze. Sign an approval message (gasless transaction) and then submit a withdrawal transaction. Select the respective vault for your tokens and click `Withdraw`. Sign the approval to allow Boosties to use your Cove LP tokens. Submit a final transaction to withdraw Yearn LP tokens. Upon withdrawal you will receive the Yearn vault token. # Using coveYFI Source: https://docs.cove.finance/how-to/coveyfi How-to guides for using coveYFI ## Using coveYFI ### Minting Users deposit **YFI** into Boosties and Cove perpetually locks it into **veYFI**. Users receive **coveYFI** in return. Staking **coveYFI** earns users **COVE**! ### Staking Staking your coveYFI earns you COVE tokens. Navigate to the YFI tab on Cove. Specify how much coveYFI you would like to stake and sign the approval message. Submit the staking transaction. Your staked coveYFI tokens will earn COVE tokens when liquidity mining begins. # Using the dYFI Redeemer Source: https://docs.cove.finance/how-to/dyfi-redeemer How-to guides for using the dYFI Redeemer ## Using the dYFI Redeemer ### Approving Users only need to approve the dYFI Redeemer contract once to participate in dYFI→YFI redemptions. Once the dYFI Redeemer contract is approved users will asynchronously start redeeming YFI for dYFI every time the Redeemer contract is called. Navigate to the YFI tab on Cove. Select Convert YFI to find the dYFI Auto Converter. Toggle the ⚙️ to approve dYFI for conversions. Submit one transaction to approve the dYFI Auto Converter to redeem your dYFI→YFI. Redemption is permissionless so any user can redeem if they wish to and are periodically processed by keeper bots. ### Revoking Users can revoke the dYFI Redeemer contract to stop participating in dYFI→YFI redemptions at any time. Navigate to the YFI tab on Cove. Select Convert YFI to find the dYFI Auto Converter. Toggle the ⚙️ to revoke dYFI permissions. Submit a transaction to revoke the dYFI Auto Converter privileges. # Introduction Source: https://docs.cove.finance/introduction Welcome to Cove — the one-stop platform for earning onchain Hero Light Hero Dark ## What is Cove? Cove pairs off-chain intelligence with on-chain automation to deliver curated 1-click DeFi vaults that earn higher, safer yield. Our first product coveUSD sets the benchmark for reliable, diversified blue chip USD yield on Ethereum. Cove is optimized by [Gauntlet](https://www.gauntlet.xyz/) and audited by [Trail of Bits](https://trailofbits.com/), [Pashov Audit Group](https://www.pashov.net/), [Zellic](https://www.zellic.io/), [Quantstamp](https://quantstamp.com/), and [yAudit](https://yaudit.dev/). ## The Cove Ecosystem The Cove ecosystem is a comprehensive suite of products designed to make onchain earning simple, safe, and powerful. It's built on the **Cove Protocol**, which uses off-chain intelligence and on-chain automation to deliver higher, safer yield. ### coveUSD coveUSD is Cove's flagship vault, delivering institutional-grade USD yield through automated capital allocation. * It automatically reallocates across top-tier strategies to maximize risk-adjusted returns. * It aims to establish the benchmark rate for safe, blue-chip USD yield on Ethereum. ### Boosties Boosties is the dedicated liquid locker and staking platform for Yearn, built with Yearn V3. * Maximize your [dYFI](https://docs.yearn.fi/getting-started/products/veyfi#dyfi) rewards from Yearn vaults without managing your own veYFI position. * Includes [coveYFI](/ecosystem/boosties/coveyfi) for liquid YFI locking and the [dYFI Redeemer](/ecosystem/boosties/dyfi-redeemer) for gas-less reward redemption. ### Cove Protocol The underlying protocol that powers the ecosystem. It provides: * A simplified way to earn onchain that abstracts away the complexity of DeFi. * Access to sophisticated strategies managed by experts like Gauntlet. * Elimination of [loss-versus-rebalancing (LVR)](https://a16zcrypto.com/posts/article/lvr-quantifying-the-cost-of-providing-liquidity-to-automated-market-makers/) through [Programmatic Orders](https://docs.cow.fi/cow-protocol/concepts/order-types/programmatic-orders) for better returns. ### \$COVE [\$COVE](/ecosystem/token) is the protocol's governance token. It is currently used for onchain governance, giving the community control over the protocol's future. It is currently non-transferable. ## Roadmap We are continuously building to make DeFi as accessible as running water. Here's what's next: * **AI-enabled strategies** powered by [Ritual](https://ritual.net/) x ████████. * Full tokenomics and onchain governance. * Cross-chain expansion and abstraction. Learn more: } href="ecosystem/protocol/cove-protocol" > Earn best-in-class yield with 1-click access to expert strategies } href="ecosystem/protocol/coveusd" > Flagship vault delivering institutional-grade USD yield } href="ecosystem/token/info" > Protocol governance token } href="ecosystem/partners/storm-labs" > Early core contributors of the Cove Protocol } href="ecosystem/boosties/boosties" > Dedicated liquid locker and staking platform for Yearn # coveYFI/YFI Curve Pool Source: https://docs.cove.finance/resources/coveyfi-curve-pool # Gauntlet coveYFI Dashboard Source: https://docs.cove.finance/resources/gauntlet-dashboard # Media Kit Source: https://docs.cove.finance/resources/media-kit # Privacy Policy Source: https://docs.cove.finance/resources/privacy-policy # Terms of Service Source: https://docs.cove.finance/resources/terms-of-service # Audits Source: https://docs.cove.finance/security/audits Smart contract audits of the Cove ecosystem Cove is committed to the highest standards of security and transparency. As part of this commitment, all major protocol upgrades and new components undergo rigorous independent audits from leading security firms. You can find a complete list of audit reports below. All reports are also available in the [cove-audits public repository](https://github.com/Storm-Labs-Inc/cove-audits). Audits are not a security guarantee. They represent a best-effort review at a specific point in time to identify potential issues. ## Cove Protocol | Auditing Firm | Date(s) | Report(s) | Focus | | :-------------------------------- | :--------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------- | | [Pashov](https://www.pashov.net/) | 2025-01-16, 2025-04-19 | [Report 1](https://github.com/Storm-Labs-Inc/cove-audits/blob/master/2025-01-16%5FPashov%5FCove.pdf), [Report 2](https://github.com/Storm-Labs-Inc/cove-audits/blob/master/2025-04-19%5FPashov%5FCove.pdf) | Cove Protocol smart contracts | | [Zellic](https://www.zellic.io/) | 2024-12-23 | [Report](https://github.com/Storm-Labs-Inc/cove-audits/blob/master/2024-12-23%5FZellic%5FCove.pdf) | Cove Protocol smart contracts | ## Cove Boosties | Auditing Firm | Date(s) | Report(s) | Focus | | :-------------------------------------------- | :--------- | :---------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- | | [yAudit](https://yaudit.dev/) | 2024-03-30 | [Report](https://github.com/Storm-Labs-Inc/cove-audits/blob/master/2024-03-30%5FyAudit%5FBoosties.pdf) | \$COVE governance token and auxiliary/reward contracts for Boosties | | [Quantstamp](https://quantstamp.com/) | 2024-03-08 | [Report](https://github.com/Storm-Labs-Inc/cove-audits/blob/master/2024-03-08%5FQuantstamp%5FBoosties.pdf) | \$COVE governance token and auxiliary, reward, and deployment contracts for Boosties | | [Trail of Bits](https://www.trailofbits.com/) | 2024-01-25 | [Report](https://github.com/Storm-Labs-Inc/cove-audits/blob/master/2024-01-25%5FTrail%5Fof%5FBits%5FBoosties.pdf) | Cove Boosties strategy contracts | Source code and audit reports are available in the following repositories: Core smart contracts of the Cove Protocol Smart contracts for Cove Boosties, the \$COVE token, and auxiliary systems. Collection of all Cove smart contract audit reports. # Bug Bounty Source: https://docs.cove.finance/security/bug-bounty Cove's Immunefi disclosure program [Bug bounty programs](https://en.wikipedia.org/wiki/Bug_bounty_program) pay security researchers ("white hats") to find and responsibly disclose vulnerabilities before attackers can exploit them. Cove hosts its bounty on [Immunefi](https://immunefi.com/), the leading platform for smart-contract security. All submissions must follow Immunefi's Responsible Disclosure Policy. Learn more or submit a report: Secure the protocol, earn rewards, help keep users safe. # Contract Addresses Source: https://docs.cove.finance/security/contract-addresses # Ethereum ## Boosties | Contract | Address | | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | AutoCompoundingGauge-yGauge crvUSD-2 yVault | [0x7c37d1Ca716c4519BEcc9bC0CEea065C88caF98B](https://etherscan.io/address/0x7c37d1Ca716c4519BEcc9bC0CEea065C88caF98B#code) | | AutoCompoundingGauge-yGauge Curve COVEYFI Factory yVault | [0x4D840966887673132Ec61aB4Ffb5e3c26cB1F4BD](https://etherscan.io/address/0x4D840966887673132Ec61aB4Ffb5e3c26cB1F4BD#code) | | AutoCompoundingGauge-yGauge Curve YFI-ETH Pool yVault | [0xf750c238cE033afC224C2E57d0fcb86E64Db0221](https://etherscan.io/address/0xf750c238cE033afC224C2E57d0fcb86E64Db0221#code) | | AutoCompoundingGauge-yGauge Curve dYFIETH-f Factory yVault | [0xb5907b7913F4dc10C5c0fc75c570c7D78D16768F](https://etherscan.io/address/0xb5907b7913F4dc10C5c0fc75c570c7D78D16768F#code) | | AutoCompoundingGauge-yGauge Curve yETH Factory yVault | [0x093f4FCA4b71912EDb33B2d4Bb92E5b85658D833](https://etherscan.io/address/0x093f4FCA4b71912EDb33B2d4Bb92E5b85658D833#code) | | AutoCompoundingGauge-yGauge DAI-1 yVault | [0x90B28aa7Df2eFaaAD4582afaF4D2a1c61519A245](https://etherscan.io/address/0x90B28aa7Df2eFaaAD4582afaF4D2a1c61519A245#code) | | AutoCompoundingGauge-yGauge DAI-2 yVault | [0x45380B6249a1005bec67928AF03b8aA8ec4eadCC](https://etherscan.io/address/0x45380B6249a1005bec67928AF03b8aA8ec4eadCC#code) | | AutoCompoundingGauge-yGauge LP Yearn CRV Vault v2 | [0x2BCc065433c608B2e71eA80405E260cA9B40ff65](https://etherscan.io/address/0x2BCc065433c608B2e71eA80405E260cA9B40ff65#code) | | AutoCompoundingGauge-yGauge LP Yearn PRISMA Vault | [0xf4e7Ff66Fd3d1c33B3020fFA575C33Cb2968082D](https://etherscan.io/address/0xf4e7Ff66Fd3d1c33B3020fFA575C33Cb2968082D#code) | | AutoCompoundingGauge-yGauge USDC-1 yVault | [0x66Afc16E2FaCf4EeA0712EDEBE0B96C5f51606Fa](https://etherscan.io/address/0x66Afc16E2FaCf4EeA0712EDEBE0B96C5f51606Fa#code) | | AutoCompoundingGauge-yGauge WETH-1 yVault | [0xED08B03bAeAB9EEF24F8AAa7c752f34a3264992e](https://etherscan.io/address/0xED08B03bAeAB9EEF24F8AAa7c752f34a3264992e#code) | | AutoCompoundingGauge-yGauge WETH-2 yVault | [0x4E69d3b01a5693DBff8dC0AD340eBF816b38D162](https://etherscan.io/address/0x4E69d3b01a5693DBff8dC0AD340eBF816b38D162#code) | | CoveToken | [0x32fb7D6E0cBEb9433772689aA4647828Cc7cbBA8](https://etherscan.io/address/0x32fb7D6E0cBEb9433772689aA4647828Cc7cbBA8#code) | | CoveYFI | [0xFf71841EeFca78a64421db28060855036765c248](https://etherscan.io/address/0xFf71841EeFca78a64421db28060855036765c248#code) | | CoveYFIRewardsGauge | [0x48302Ba7bCdF2bD59D20F8893C0F11b431A3be24](https://etherscan.io/address/0x48302Ba7bCdF2bD59D20F8893C0F11b431A3be24#code) | | CoveYFIRewardsGaugeRewardForwarder | [0x3BdeF86A2E4c5c3661158017cb9bF78fd91DB9E8](https://etherscan.io/address/0x3BdeF86A2E4c5c3661158017cb9bF78fd91DB9E8#code) | | CoveYearnGaugeFactory | [0x842b22Eb2A1C1c54344eDdbE6959F787c2d15844](https://etherscan.io/address/0x842b22Eb2A1C1c54344eDdbE6959F787c2d15844#code) | | DYFIRedeemer | [0x986F38B5b096070eE64B12Da762468606C8B0706](https://etherscan.io/address/0x986F38B5b096070eE64B12Da762468606C8B0706#code) | | ERC20RewardsGaugeImpl | [0xB5ed89e400B1EdAe5a0a307e0C2196116F543605](https://etherscan.io/address/0xB5ed89e400B1EdAe5a0a307e0C2196116F543605#code) | | GaugeRewardReceiverImplementation | [0x9AA729FA58e8298AaEC4C4c33189ED137B3B74f0](https://etherscan.io/address/0x9AA729FA58e8298AaEC4C4c33189ED137B3B74f0#code) | | MasterRegistry | [0x91cf20C03bEC656BC008fB2a2177bC3caA34f772](https://etherscan.io/address/0x91cf20C03bEC656BC008fB2a2177bC3caA34f772#code) | | MiniChefV3 | [0x53eaD38ca96D562433427f7Bbfcac960cC1F2E2d](https://etherscan.io/address/0x53eaD38ca96D562433427f7Bbfcac960cC1F2E2d#code) | | RewardForwarderImpl | [0xbB17Be6a283D7D18836a6F44dFB45F9D9CE2CE64](https://etherscan.io/address/0xbB17Be6a283D7D18836a6F44dFB45F9D9CE2CE64#code) | | Staging\_MasterRegistry | [0x44bb20e5a3cc2cbdfb7520aa76281019723382cb](https://etherscan.io/address/0x44bb20e5a3cc2cbdfb7520aa76281019723382cb#code) | | StakingDelegateRewards | [0xf91E84E2E4f692e6d8F7440639d5C2147f4C06F0](https://etherscan.io/address/0xf91E84E2E4f692e6d8F7440639d5C2147f4C06F0#code) | | SwapAndLock | [0x9dadf9487737DE29ac685d231bB94348a2635CBb](https://etherscan.io/address/0x9dadf9487737DE29ac685d231bB94348a2635CBb#code) | | TimelockController | [0x705F82BB431fAdA1a0F11D7b77B3f0586c545CBc](https://etherscan.io/address/0x705F82BB431fAdA1a0F11D7b77B3f0586c545CBc#code) | | YSDRewardsGaugeImpl | [0x15dDAd641337Ce39e63F1e4F659B2a9c2c2D711B](https://etherscan.io/address/0x15dDAd641337Ce39e63F1e4F659B2a9c2c2D711B#code) | | Yearn4626RouterExt (Deprecated) | [0x3327744318b8B0eE79159B7f742fe0b378f93df8](https://etherscan.io/address/0x3327744318b8B0eE79159B7f742fe0b378f93df8#code) | | Yearn4626RouterExt | [0x15633dc0ce383babc96fdcdabf08a29e87ce53e3](https://etherscan.io/address/0x15633dc0ce383babc96fdcdabf08a29e87ce53e3#code) | | YearnGaugeStrategy-yGauge Curve COVEYFI Factory yVault | [0xF96E4C5Eee8095F918eD3312B3De3d68156798f8](https://etherscan.io/address/0xF96E4C5Eee8095F918eD3312B3De3d68156798f8#code) | | YearnGaugeStrategy-yGauge Curve YFI-ETH Pool yVault | [0x552868611d2641144454140DdED98E6160b3Bfc9](https://etherscan.io/address/0x552868611d2641144454140DdED98E6160b3Bfc9#code) | | YearnGaugeStrategy-yGauge Curve dYFIETH-f Factory yVault | [0x120B128cF1a5117Fe8E9E12b79B3437e7396bd14](https://etherscan.io/address/0x120B128cF1a5117Fe8E9E12b79B3437e7396bd14#code) | | YearnGaugeStrategy-yGauge Curve yETH Factory yVault | [0x18f365ECCe58fA865Ec9FB027E9175125DB93B91](https://etherscan.io/address/0x18f365ECCe58fA865Ec9FB027E9175125DB93B91#code) | | YearnGaugeStrategy-yGauge crvUSD-2 yVault | [0x64DC55D76d1541E0853cbd7cF6586615e9E6f4C7](https://etherscan.io/address/0x64DC55D76d1541E0853cbd7cF6586615e9E6f4C7#code) | | YearnGaugeStrategy-yGauge DAI-1 yVault | [0x28b2DC219c047B10F353caA2934ad8803e089A88](https://etherscan.io/address/0x28b2DC219c047B10F353caA2934ad8803e089A88#code) | | YearnGaugeStrategy-yGauge DAI-2 yVault | [0x9Cb8c5136aD079d3311F5b766D6fC370bF29E76b](https://etherscan.io/address/0x9Cb8c5136aD079d3311F5b766D6fC370bF29E76b#code) | | YearnGaugeStrategy-yGauge LP Yearn CRV Vault v2 | [0xfe08Fc631BE2DA2B47aa6adBA275ADAB2197C0cd](https://etherscan.io/address/0xfe08Fc631BE2DA2B47aa6adBA275ADAB2197C0cd#code) | | YearnGaugeStrategy-yGauge LP Yearn PRISMA Vault | [0x6568921f9059B6b8a3902651783A7A0E74Ca83fF](https://etherscan.io/address/0x6568921f9059B6b8a3902651783A7A0E74Ca83fF#code) | | YearnGaugeStrategy-yGauge USDC-1 yVault | [0x87588D3fBCdff1bF84555F0A22056d94534A74A6](https://etherscan.io/address/0x87588D3fBCdff1bF84555F0A22056d94534A74A6#code) | | YearnGaugeStrategy-yGauge USDS-1 yVault | [0x81f78DeF7a3a8B0F6aABa69925efC69E70239D95](https://etherscan.io/address/0x81f78DeF7a3a8B0F6aABa69925efC69E70239D95#code) | | YearnGaugeStrategy-yGauge WETH-1 yVault | [0x81D40243c649f7d6092295F50F4B1D3A8e53DA99](https://etherscan.io/address/0x81D40243c649f7d6092295F50F4B1D3A8e53DA99#code) | | YearnGaugeStrategy-yGauge WETH-2 yVault | [0x29eE8c3FB7ea0b52261B18782F1a060C2e210aFa](https://etherscan.io/address/0x29eE8c3FB7ea0b52261B18782F1a060C2e210aFa#code) | | YearnStakingDelegate | [0x05dcdBF02F29239D1f8d9797E22589A2DE1C152F](https://etherscan.io/address/0x05dcdBF02F29239D1f8d9797E22589A2DE1C152F#code) | ## Cove | Contract | Address | | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | AnchoredOracle\_sfrxUSD-USD | [0x599C797e614a3ea6d7b63F9C67c49b239b45653F](https://etherscan.io/address/0x599C797e614a3ea6d7b63F9C67c49b239b45653F#code) | | AnchoredOracle\_sUSDe-USD | [0x37BD278CE3F0025fC18086dA11e4C5f8f8B2b885](https://etherscan.io/address/0x37BD278CE3F0025fC18086dA11e4C5f8f8B2b885#code) | | AnchoredOracle\_USDC-USD | [0xC77e0E5FD366F606bEc809da0AF3Df364213356f](https://etherscan.io/address/0xC77e0E5FD366F606bEc809da0AF3Df364213356f#code) | | AnchoredOracle\_ysUSDC-USD | [0x8B994ebcD44413Ee84D2733750b2006a7635FF1E](https://etherscan.io/address/0x8B994ebcD44413Ee84D2733750b2006a7635FF1E#code) | | AnchoredOracle\_ysyG-yvUSDS-1-USD | [0x5CaAE6658F16409e175D93554530d773B71242E3](https://etherscan.io/address/0x5CaAE6658F16409e175D93554530d773B71242E3#code) | | AssetRegistry | [0xD57950e8E9111cA49B1a041eD6c53a1355e317C7](https://etherscan.io/address/0xD57950e8E9111cA49B1a041eD6c53a1355e317C7#code) | | BasketManager | [0x716c39658Ba56Ce34bdeCDC1426e8768E61912f8](https://etherscan.io/address/0x716c39658Ba56Ce34bdeCDC1426e8768E61912f8#code) | | BasketManagerUtils | [0x4Cb99eb83A0AbED477C4A99234BC58e0464aA280](https://etherscan.io/address/0x4Cb99eb83A0AbED477C4A99234BC58e0464aA280#code) | | BasketToken\_USD (CoveUSD) | [0xEeA3Edc017877C603E2F332FC1828a46432cdF96](https://etherscan.io/address/0xEeA3Edc017877C603E2F332FC1828a46432cdF96#code) | | BasketTokenImplementation | [0xaAfA26aA70e7E1119B32fDb2dfc07f8e3EBA0987](https://etherscan.io/address/0xaAfA26aA70e7E1119B32fDb2dfc07f8e3EBA0987#code) | | ChainedERC4626Oracle\_ysyG-yvUSDS-1-USDS | [0x38681b1096F5a67286094dEacbB112a0848b1e21](https://etherscan.io/address/0x38681b1096F5a67286094dEacbB112a0848b1e21#code) | | ChainlinkOracle\_USDC-USD | [0x4137CaE916696eaA776443c8D4Db832988C2Bab3](https://etherscan.io/address/0x4137CaE916696eaA776443c8D4Db832988C2Bab3#code) | | ChainlinkOracle\_USDe-USD | [0x60C15150f094840972269f2d758FFD9D82d329Fe](https://etherscan.io/address/0x60C15150f094840972269f2d758FFD9D82d329Fe#code) | | ChainlinkOracle\_USDS-USD | [0x0fFCBFe3034E9f7139c367d52f2668b6B878A82F](https://etherscan.io/address/0x0fFCBFe3034E9f7139c367d52f2668b6B878A82F#code) | | CowSwapAdapter | [0xc50DD21a8515CbFd597D65c8Fe9f4653F1B1D35B](https://etherscan.io/address/0xc50DD21a8515CbFd597D65c8Fe9f4653F1B1D35B#code) | | CoWSwapCloneImplementation | [0xd0b1d686f1EC4879add3Bee2dD0f0befb0C2cE68](https://etherscan.io/address/0xd0b1d686f1EC4879add3Bee2dD0f0befb0C2cE68#code) | | CrossAdapter\_sfrxUSD-frxUSD-USD\_4626-Pyth | [0x7a82ceD9334aEc14304842fA758E8A9731AC4E9c](https://etherscan.io/address/0x7a82ceD9334aEc14304842fA758E8A9731AC4E9c#code) | | CrossAdapter\_sfrxUSD-frxUSD-USDe\_4626-CurveEMAUnderlying | [0xF5CC28c0727473a9611d09654437474BECeE0221](https://etherscan.io/address/0xF5CC28c0727473a9611d09654437474BECeE0221#code) | | CrossAdapter\_sfrxUSD-USDe-USD\_CrossAdapter-Chainlink | [0x60Cf6c24FF5636B0B35e481cB91A57e9F8A6679D](https://etherscan.io/address/0x60Cf6c24FF5636B0B35e481cB91A57e9F8A6679D#code) | | CrossAdapter\_sUSDe-USDe-USD\_4626-Chainlink | [0xE2C3844529c4F5B77fBC692Fe1456136AfD6AFb0](https://etherscan.io/address/0xE2C3844529c4F5B77fBC692Fe1456136AfD6AFb0#code) | | CrossAdapter\_ysUSDC-USDC-USD\_4626-Chainlink | [0xf58CEE791A1A752Ee57B4d7DF94083D0916b9Ff6](https://etherscan.io/address/0xf58CEE791A1A752Ee57B4d7DF94083D0916b9Ff6#code) | | CrossAdapter\_ysUSDC-USDC-USD\_4626-Pyth | [0x44aa6fd2B4c6Fe413bB1C11B9E94C8E80879E7d2](https://etherscan.io/address/0x44aa6fd2B4c6Fe413bB1C11B9E94C8E80879E7d2#code) | | CrossAdapter\_ysyG-yvUSDS-1-USDS-USD\_ChainedERC4626-Chainlink | [0xe082A5CC8EabBF57af5F286fA258AacD2Ab0F6DC](https://etherscan.io/address/0xe082A5CC8EabBF57af5F286fA258AacD2Ab0F6DC#code) | | CrossAdapter\_ysyG-yvUSDS-1-USDS-USD\_ChainedERC4626-Pyth | [0x6d0cec5bD7D8A9292C9cbf9107664eDc2ACF42Da](https://etherscan.io/address/0x6d0cec5bD7D8A9292C9cbf9107664eDc2ACF42Da#code) | | CurveEMAOracleUnderlying\_USDe-frxUSD | [0x2772a1464024d6FCAb5FC75d379Eee928e2966B9](https://etherscan.io/address/0x2772a1464024d6FCAb5FC75d379Eee928e2966B9#code) | | ERC4626Oracle\_sfrxUSD-frxUSD | [0x4e1ac601BeCc4F55D676357FEDb759eC240a2c57](https://etherscan.io/address/0x4e1ac601BeCc4F55D676357FEDb759eC240a2c57#code) | | ERC4626Oracle\_sUSDe-USDe | [0x233b7b16278640c022cBC6f6fBf5d2dAa741BCC3](https://etherscan.io/address/0x233b7b16278640c022cBC6f6fBf5d2dAa741BCC3#code) | | ERC4626Oracle\_ysUSDC-USDC | [0xE73d409b0c91B8214eAf7fCf7521F0cCa46492A6](https://etherscan.io/address/0xE73d409b0c91B8214eAf7fCf7521F0cCa46492A6#code) | | EulerRouter | [0xECC9556F546950619e84C5C70FDF19D89dB8Aad7](https://etherscan.io/address/0xECC9556F546950619e84C5C70FDF19D89dB8Aad7#code) | | FarmingPlugin\_coveUSD\_COVERewards | [0xa74e0B738b053D9083451bBAB84c538ff2Cc701d](https://etherscan.io/address/0xa74e0B738b053D9083451bBAB84c538ff2Cc701d#code) | | FarmingPluginFactory | [0xD46D6161bBB2103Da01987430de8B9C4756DF8f6](https://etherscan.io/address/0xD46D6161bBB2103Da01987430de8B9C4756DF8f6#code) | | FeeCollector | [0x9219401e7E2e473770E56203e4EebA85083C7f7E](https://etherscan.io/address/0x9219401e7E2e473770E56203e4EebA85083C7f7E#code) | | ManagedWeightStrategy\_Gauntlet V1 | [0x80a42c54D57654a4b3bb82281EED797419EF165F](https://etherscan.io/address/0x80a42c54D57654a4b3bb82281EED797419EF165F#code) | | MasterRegistry | [0x91cf20C03bEC656BC008fB2a2177bC3caA34f772](https://etherscan.io/address/0x91cf20C03bEC656BC008fB2a2177bC3caA34f772#code) | | PythOracle\_frxUSD-USD | [0xe501dFEc659Da3a3BB5901634EBb34be10B70af5](https://etherscan.io/address/0xe501dFEc659Da3a3BB5901634EBb34be10B70af5#code) | | PythOracle\_sUSDe-USD | [0x0eF805362304d1a1EF1444f5b411FE96Dec663eB](https://etherscan.io/address/0x0eF805362304d1a1EF1444f5b411FE96Dec663eB#code) | | PythOracle\_USDC-USD | [0xc87aDB71e67A03c4bB43F12eaBa39eF1BA423605](https://etherscan.io/address/0xc87aDB71e67A03c4bB43F12eaBa39eF1BA423605#code) | | PythOracle\_USDS-USD | [0xCD534167eC52ba2f4D81915E5331e841074C93a3](https://etherscan.io/address/0xCD534167eC52ba2f4D81915E5331e841074C93a3#code) | | StrategyRegistry | [0xB97C12781FB1De1F07B4735526db7B3420F26F99](https://etherscan.io/address/0xB97C12781FB1De1F07B4735526db7B3420F26F99#code) | | TimelockController | [0x705F82BB431fAdA1a0F11D7b77B3f0586c545CBc](https://etherscan.io/address/0x705F82BB431fAdA1a0F11D7b77B3f0586c545CBc#code) | ## Cove Staging | Contract | Address | | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | AnchoredOracle\_sfrxUSD-USD | [0x00EB79cf7917c3cDD30755a5f4BBF5A47bc933C1](https://etherscan.io/address/0x00EB79cf7917c3cDD30755a5f4BBF5A47bc933C1#code) | | AnchoredOracle\_sUSDe-USD | [0x8127FF19FE0Bf8Bd450342B42ef2503747077ea4](https://etherscan.io/address/0x8127FF19FE0Bf8Bd450342B42ef2503747077ea4#code) | | AnchoredOracle\_USDC-USD | [0x818a26d44Bf9D3ec5F1A0f1d789cb1a1C7CbA040](https://etherscan.io/address/0x818a26d44Bf9D3ec5F1A0f1d789cb1a1C7CbA040#code) | | AnchoredOracle\_ysUSDC-USD | [0x3666F2c7273a3a0CEd0F5FfC684c75E04B050396](https://etherscan.io/address/0x3666F2c7273a3a0CEd0F5FfC684c75E04B050396#code) | | AnchoredOracle\_ysyG-yvUSDS-1-USD | [0xF9A022F25993f5E122b11cF836CBb7F2e1A5a8ae](https://etherscan.io/address/0xF9A022F25993f5E122b11cF836CBb7F2e1A5a8ae#code) | | AssetRegistry | [0xFe53C6c84FD87adfD50c0392A5994239E0C07FfD](https://etherscan.io/address/0xFe53C6c84FD87adfD50c0392A5994239E0C07FfD#code) | | BasicRetryOperator | [0xC7f2Cf4845C6db0e1a1e91ED41Bcd0FcC1b0E141](https://etherscan.io/address/0xC7f2Cf4845C6db0e1a1e91ED41Bcd0FcC1b0E141#code) | | BasketManager | [0xbeccf8486856476E9Cd8AD6FaD80Fb7c17a15Da1](https://etherscan.io/address/0xbeccf8486856476E9Cd8AD6FaD80Fb7c17a15Da1#code) | | BasketManagerUtils | [0x630101fB844d911e5C0239c28E17ceBf3C669FEe](https://etherscan.io/address/0x630101fB844d911e5C0239c28E17ceBf3C669FEe#code) | | BasketToken\_Stables | [0x9f53dA1E245207e163E71DFC45dAFaB2d01770d0](https://etherscan.io/address/0x9f53dA1E245207e163E71DFC45dAFaB2d01770d0#code) | | BasketTokenImplementation | [0x275423F55C872b53F9b0767D830F173fb11ab6C5](https://etherscan.io/address/0x275423F55C872b53F9b0767D830F173fb11ab6C5#code) | | ChainedERC4626Oracle\_ysyG-yvUSDS-1-USDS | [0xf33958E73B8A1325af667598154948557C3Dd0ea](https://etherscan.io/address/0xf33958E73B8A1325af667598154948557C3Dd0ea#code) | | ChainlinkOracle\_DAI-USD | [0x6715b6efE1cad9A68821e42335911F717e422107](https://etherscan.io/address/0x6715b6efE1cad9A68821e42335911F717e422107#code) | | ChainlinkOracle\_FRAX-USD | [0xA55615296DD227A8a90f6a6789FEaf1e4f1Bbf3D](https://etherscan.io/address/0xA55615296DD227A8a90f6a6789FEaf1e4f1Bbf3D#code) | | ChainlinkOracle\_sUSDe-USD | [0x55aC02d9539e3A877e1245dc0de08eE2235B5DB2](https://etherscan.io/address/0x55aC02d9539e3A877e1245dc0de08eE2235B5DB2#code) | | ChainlinkOracle\_USDC-USD | [0x4289313F8d7d65f6c16830B2B4Aa5cf868e3C239](https://etherscan.io/address/0x4289313F8d7d65f6c16830B2B4Aa5cf868e3C239#code) | | ChainlinkOracle\_USDE-USD | [0xC1BE5cA2a39ecAfb2d339E6E4927A35b5f7D78Ca](https://etherscan.io/address/0xC1BE5cA2a39ecAfb2d339E6E4927A35b5f7D78Ca#code) | | ChainlinkOracle\_USDS-USD | [0x087f2B76AEDf6D7D103E780c31694641f2506c48](https://etherscan.io/address/0x087f2B76AEDf6D7D103E780c31694641f2506c48#code) | | CoveMockERC20 | [0x062638326fD5Efd369921D034664c9de20B9ABA2](https://etherscan.io/address/0x062638326fD5Efd369921D034664c9de20B9ABA2#code) | | CoWSwapAdapter | [0x1db6482f07B223fad08E8Ec4648024601b2dA7Ad](https://etherscan.io/address/0x1db6482f07B223fad08E8Ec4648024601b2dA7Ad#code) | | CoWSwapCloneImplementation | [0x9D677eD832D57588217593c8B4e3530825788d0d](https://etherscan.io/address/0x9D677eD832D57588217593c8B4e3530825788d0d#code) | | CrossAdapter\_sDAI-DAI-USD\_4626-Chainlink | [0x9523aFe79AA6A103f7cF9D4B869ad49504402b63](https://etherscan.io/address/0x9523aFe79AA6A103f7cF9D4B869ad49504402b63#code) | | CrossAdapter\_sFRAX-FRAX-USD\_4626-Chainlink | [0xD918e89c5D8abF185C4BA6c02603Ac32C7B796af](https://etherscan.io/address/0xD918e89c5D8abF185C4BA6c02603Ac32C7B796af#code) | | CrossAdapter\_sfrxUSD-frxUSD-USD\_4626-Pyth | [0x5EBa4D939902B9AEC74668A6A06229a8731caf11](https://etherscan.io/address/0x5EBa4D939902B9AEC74668A6A06229a8731caf11#code) | | CrossAdapter\_sfrxUSD-frxUSD-USDe\_4626-CurveEMAUnderlying | [0x766De20aC7E282a32F5Fd37D64D055afcA7431A3](https://etherscan.io/address/0x766De20aC7E282a32F5Fd37D64D055afcA7431A3#code) | | CrossAdapter\_sfrxUSD-USDe-USD\_CrossAdapter-Chainlink | [0x319805e6350a8607098aDec6aeEdC1D54cb01567](https://etherscan.io/address/0x319805e6350a8607098aDec6aeEdC1D54cb01567#code) | | CrossAdapter\_sUSDe-USDe-USD\_4626-Chainlink | [0x811dA0c02713DF17dA35F0041c1cA7df016deE62](https://etherscan.io/address/0x811dA0c02713DF17dA35F0041c1cA7df016deE62#code) | | CrossAdapter\_ysUSDC-USDC-USD\_4626-Chainlink | [0xbF1d5C413E7430a71b552b3562F545d3a74Cd95C](https://etherscan.io/address/0xbF1d5C413E7430a71b552b3562F545d3a74Cd95C#code) | | CrossAdapter\_ysUSDC-USDC-USD\_4626-Pyth | [0x1a9D613a8793E03374215df039d234c0fB94c091](https://etherscan.io/address/0x1a9D613a8793E03374215df039d234c0fB94c091#code) | | CrossAdapter\_ysyG-yvUSDS-1-USDS-USD\_ChainedERC4626-Chainlink | [0xD0012c0064059Ba87cB754BD60794fc29E1Ab41e](https://etherscan.io/address/0xD0012c0064059Ba87cB754BD60794fc29E1Ab41e#code) | | CrossAdapter\_ysyG-yvUSDS-1-USDS-USD\_ChainedERC4626-Pyth | [0xC9Bc3042701EbbACDb562C7928172f3235f1fA97](https://etherscan.io/address/0xC9Bc3042701EbbACDb562C7928172f3235f1fA97#code) | | CurveEMAOracleUnderlying\_USDe-frxUSD | [0x36230d01F8516CBBd3f787F319356C91B6D5022C](https://etherscan.io/address/0x36230d01F8516CBBd3f787F319356C91B6D5022C#code) | | ERC4626Oracle\_sDAI-DAI | [0x01Dc22D46d8CF6100AB91fBb4e614c52f8cc726E](https://etherscan.io/address/0x01Dc22D46d8CF6100AB91fBb4e614c52f8cc726E#code) | | ERC4626Oracle\_sFRAX-FRAX | [0xEFDbac6cB4BBC7B814aC15E2C1b3973E433820cD](https://etherscan.io/address/0xEFDbac6cB4BBC7B814aC15E2C1b3973E433820cD#code) | | ERC4626Oracle\_sfrxUSD-frxUSD | [0xB52dBE41eDaaf39E67E0DB65CD99B903B2798360](https://etherscan.io/address/0xB52dBE41eDaaf39E67E0DB65CD99B903B2798360#code) | | ERC4626Oracle\_sUSDe-USDe | [0x62F56c76FCA998F6f7c798b31Ef1E8968018C7ce](https://etherscan.io/address/0x62F56c76FCA998F6f7c798b31Ef1E8968018C7ce#code) | | ERC4626Oracle\_ysUSDC-USDC | [0xFCa447b7Da9E3d66B6BaA7a7d8efFB78F4D85e5A](https://etherscan.io/address/0xFCa447b7Da9E3d66B6BaA7a7d8efFB78F4D85e5A#code) | | EulerRouter | [0xc8570fa08D87958C319212e5de2aDEdBc41d0190](https://etherscan.io/address/0xc8570fa08D87958C319212e5de2aDEdBc41d0190#code) | | FarmingPlugin\_cvtstgUSD\_E20MRewards | [0x27BdAAdfDc0c3E39ad38C86f2f1774B51E4D237e](https://etherscan.io/address/0x27BdAAdfDc0c3E39ad38C86f2F1774B51E4D237e#code) | | FarmingPluginFactory | [0xC79154E5a656b33D35bd283701657a6C8592dEBA](https://etherscan.io/address/0xC79154E5a656b33D35bd283701657a6C8592dEBA#code) | | FeeCollector | [0x3F0de00c4332121764837c7bbd30bB9Cb66b0A61](https://etherscan.io/address/0x3F0de00c4332121764837c7bbd30bB9Cb66b0A61#code) | | ManagedWeightStrategy\_Gauntlet V1 | [0x118b214008d3c693f0fC3434EF24F28e23EF7254](https://etherscan.io/address/0x118b214008d3c693f0fC3434EF24F28e23EF7254#code) | | MasterRegistry | [0x44bb20e5a3cc2cbdfb7520aa76281019723382cb](https://etherscan.io/address/0x44bb20e5a3cc2cbdfb7520aa76281019723382cb#code) | | PythOracle\_DAI-USD | [0xed2df346aCF926DAC0F15c47AA040ad4dB224696](https://etherscan.io/address/0xed2df346aCF926DAC0F15c47AA040ad4dB224696#code) | | PythOracle\_frxUSD-USD | [0x846601F1c6d11C90ffA72e40c21A28eFC30d1812](https://etherscan.io/address/0x846601F1c6d11C90ffA72e40c21A28eFC30d1812#code) | | PythOracle\_sDAI-USD | [0x11D92f0A6eDFa9d577D88B32556864D8662eC09D](https://etherscan.io/address/0x11D92f0A6eDFa9d577D88B32556864D8662eC09D#code) | | PythOracle\_sUSDe-USD | [0x3Ab78218944cBDeB35c09E0E1b38F1120CE97612](https://etherscan.io/address/0x3Ab78218944cBDeB35c09E0E1b38F1120CE97612#code) | | PythOracle\_USDC-USD | [0x4e4a2240eC517C45b44AAb35bB3c343b22e6A6D8](https://etherscan.io/address/0x4e4a2240eC517C45b44AAb35bB3c343b22e6A6D8#code) | | PythOracle\_USDS-USD | [0x06fAa7646AE8001097EdFfd2217c341A54B472Dc](https://etherscan.io/address/0x06fAa7646AE8001097EdFfd2217c341A54B472Dc#code) | | StrategyRegistry | [0x5877f26793c44358B0757617f4e3380C344fF523](https://etherscan.io/address/0x5877f26793c44358B0757617f4e3380C344fF523#code) | | TimelockController | [0xF395339b12642aC27e08E72fE8aBEA0dc3a956A8](https://etherscan.io/address/0xF395339b12642aC27e08E72fE8aBEA0dc3a956A8#code) | # Base ## Cove | Contract | Address | | -------------- | -------------------------------------------------------------------------------------------------------------------------- | | MasterRegistry | [0x2f507F98a22b5f5c17423Aa8365eAef5bc6Efe0f](https://basescan.org/address/0x2f507F98a22b5f5c17423Aa8365eAef5bc6Efe0f#code) | ## Cove Staging | Contract | Address | | -------------- | -------------------------------------------------------------------------------------------------------------------------- | | MasterRegistry | [0x44bB20e5A3CC2cBdfB7520Aa76281019723382Cb](https://basescan.org/address/0x44bB20e5A3CC2cBdfB7520Aa76281019723382Cb#code) | # Risks Source: https://docs.cove.finance/security/risks Risks of using the Cove Protocol Cove is built to prioritize safety and security. However, engaging with smart contracts intrinsically carries certain risks. ## Potential Risks Potential risks include, but are not limited to: ### Smart Contract Risks * **Complex Interactions**: The protocol involves complex interactions between multiple contracts which increases the risk of unforeseen bugs. * **Integration Dependencies**: Reliance on external protocols (like Yearn) means that bugs or changes in those systems could adversely affect this protocol. ### Financial Risks * **Asset Volatility**: The underlying assets are subject to high volatility which can lead to significant changes in value. * **Yield Farming Risks**: Strategies involving yield farming are exposed to smart contract risks of the platforms they interact with. ### Governance Risks * **Governance Attacks**: The protocol may be vulnerable to governance attacks if token distribution is not sufficiently decentralized. ### Technical Risks * **Gas Costs**: High gas costs could make the protocol uneconomical for users, especially during network congestion. ### Systemic Risks * **Protocol Interconnectivity**: The high degree of interconnectivity with other DeFi protocols could lead to cascading failures if one protocol is compromised. * **Smart Contract Exploits**: The protocol could be subject to exploits due to vulnerabilities in smart contracts, leading to loss of user funds. # Access Controls Source: https://docs.cove.finance/technical/boosties/access-controls Access controls for Boosties Access control in smart contracts is a critical security measure that ensures only authorized addresses can execute certain functions. It's often managed through roles that define specific permissions, like token minting or contract pausing. Libraries like OpenZeppelin's [Ownable](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) and [AccessControl](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control) provide standardized solutions for managing these permissions, helping to safeguard the protocol's integrity and security. ## Roles * `DEFAULT_ADMIN_ROLE` * Granted to Community Multisig (3 out of 7) * For rescuing funds and pausing * `_TIMELOCK_ROLE` * To be granted to a Timelock Controller owned by the Community Multisig after initial setups * For managing user reward impacting functionalities * For setting permissioned address such as treasury address * For setting fee parameters * `_MANAGER_ROLE` * Granted to ops multisig (2 out of 4) * For managing non-user fund impacting functions * Adding new entries to MasterRegistry and YearnGaugeFactory * `_PAUSER_ROLE` * Granted to EOA / OZ Defender * For limiting attack vectors in emergencies * Stops new deposits * `_MINTER_ROLE` * Granted to Community Multisig * Used in CoveToken contract * Able to call `mint()` ## Contracts ### CoveToken * \_TIMELOCK\_ROLE * addAllowedSender(address target) * removeAllowedSender(address target) * addAllowedReceiver(address target) * removeAllowedReceiver(address target) * \_MINTER\_ROLE * mint() * *Mints tokens to a specified address* ### CoveYearnGaugeFactory * *DEFAULT\_ADMIN\_ROLE* * setRewardForwarderImplementation(address impl) * setYsdRewardsGaugeImplementation(address impl) * setTreasuryMultisig(address multisig) * setERC20RewardsGaugeImplementation(address impl) * setGaugeAdmin(address admin) * *\_MANAGER\_ROLE* * deployCoveGauges() ### BaseRewardsGauge * *DEFAULT\_ADMIN\_ROLE* * pause() * unpause() * *\_MANAGER\_ROLE* * addReward() * setRewardDistributor() \*also allowed from current distributor * \_PAUSER\_ROLE * pause() ### MiniChefV3 * *DEFAULT\_ADMIN\_ROLE* * rescue() * pause() * unpause() * *\_TIMELOCK\_ROLE* * add() * *Add a new LP to the pool with an allocpoint* * set() * *Update the given pool's REWARD\_TOKEN allocation point and `IRewarder` contract* * setRewardPerSecond() * \_PAUSER\_ROLE * pause() ### RewardForwarder * *DEFAULT\_ADMIN\_ROLE* * setTreasury() * setTreasuryBps() ### YearnGaugeStrategy * Roles come from BaseStrategy / TokenizedStrategy * onlyManagement() \*\*note: management is only given to one address — TokenizedStrategy * setPendingManagement() * setKeeper() * setEmergencyAdmin(); * setPerformanceFee(); * setPerformanceFeeRecipient(); * setProfitMaxUnlockTime(); — YearnGaugeStrategy * setHarvestSwapParams() * setMaxTotalAssets(); * setDYfiRedeemer(); * onlyKeepers() \*\* note: this modifier is truly isKeeperOrManagement(), so access can be given to an autonomous keeper and manager at the same time * report(): *Function for keepers to call to harvest and record all profits accrued* * *should be called through protected relays if swaps are going to happen* (which they will) * onlyEmergencyAuthorized() \*\*note: this modifier is truly emergencyAdmin OR management * emergencyAdmin can only be given to one address * shutdownStrategy() * *Used to shutdown the strategy preventing any further deposits* * \_strategyStorage().shutdown = true; * *Can only be called by the current `management` or `emergencyAdmin`* * emergencyWithdraw() * *To manually withdraw funds from the yield source after a strategy has been shut down* ### CoveYFI * *DEFAULT\_ADMIN\_ROLE* * rescue() ### DYfiRedeemer * DEFAULT\_ADMIN\_ROLE * setSlippage() * *Sets the slippage that should be applied to DYFI -> YFI redeems* * kill() * \_pause() ### GaugeRewardReceiver * *DEFAULT\_ADMIN\_ROLE* * rescue() ### MasterRegistry * *DEFAULT\_ADMIN\_ROLE* * grantRole(*\_MANAGER\_ROLE)* * *\_MANAGER\_ROLE* * also given to *DEFAULT\_ADMIN\_ROLE admin* * addRegistry() * updateRegistry() ### StakingDelegateRewards * *DEFAULT\_ADMIN\_ROLE* * recoverERC20() * *Allows recovery of ERC20 tokens other than the staking and rewards tokens* * *\_TIMELOCK\_ROLE* * setRewardsDuration() * *Sets the duration of the rewards period for a given staking token* ### SwapAndLock * *DEFAULT\_ADMIN\_ROLE* * setDYfiRedeemer() * *Sets the address of the DYfiRedeemer contract and approves it to spend dYFI* ### YearnStakingDelegate * *DEFAULT\_ADMIN\_ROLE* * rescueYfi() * rescueDYfi() * pause() * unpause() * addGaugeRewards() * Allowing new gauge deposits, does not need to be timelock’d * \_TIMELOCK\_ROLE * setSwapAndLock() * setGaugeRewardSplit() * setSnapshotDelegate() * updateGaugeRewards() * setPerpetualLock() * earlyUnlock() * execute() * \_PAUSER\_ROLE * pause() # Forge Docs (mdbook) Source: https://docs.cove.finance/technical/boosties/forge-docs # Boosties RFC Source: https://docs.cove.finance/technical/boosties/rfc Technical documentation and architecture for Boosties # Summary This RFC proposes the implementation of a smart contract system on the Ethereum network, onboarding users of all types to receive the benefit of YearnV3 without requiring both **veYFI** and gauge tokens to receive boosted **dYFI** yield. # Background Yearn is launching V3 of their vaults, which will now comply with the ERC-4626 standard, alongside their **veYFI** voting token model for emitting a new reward token, **dYFI**, for staking their Vault assets also known as Yearn Vault tokens (examples include YFI/ETH Curve LP token vault, WETH/yETH Curve LP token Vault, etc). ### Related reading * [\[Proposal\] Activate veYFI rewards with oYFI Gauges - Protocol and Governance - yearn.finance](https://gov.yearn.fi/t/yip-73-activate-veyfi-rewards-with-oyfi-gauges/13414/1) * [veYFI](https://github.com/yearn/veYFI) * [dYFI](https://docs.yearn.fi/getting-started/products/veyfi#dyfi) # Problem For users to receive **dYFI**, they will need to provide both **veYFI** and Yearn V3 vault tokens proportionally for maximum boost. This design is meant to dissuade large depositors from easily gaining dYFI and thus skewing the system. This design of the ve-token system creates 3 groups of users that face dilemmas on how to split their investments for maximum benefit. * Users with veYFI holdings but no vault tokens to provide * Without vault tokens to stake, users only receive dYFI from the dYFI penalty, missing out on the full benefit of the veYFI boost. * Users with Gauge tokens but no veYFI * Without veYFI, these users only receive 1x (base rate) of dYFI emission when staking their vault tokens. Even if the users were to trade all of their received dYFI to veYFI at every epoch, there is no guarantee that their boost will be much higher due to other users who receive higher dYFI emission, up to 10x boost, which gives them significant advantage in maintaining their share of veYFI. * Users who receive dYFI emission but who does not wish to manually redeem or trade claimed dYFI. * Users who wants to automate dYFI → YFI redeem process * ex. veYFI holders, StakeDAO users This RFC proposes a smart contract system for allowing both set of users to reap benefit of the **dYFI** emission without needing to provide both **veYFI** or vault tokens. Additionally, we offer a contract that can be utilized by the public for automatic and effective dYFI redemptions for any recipients of dYFI emission. ## Goals Through Cove’s tokenized strategies that wrap around Yearn’s gauges for dYFI emissions, users are able to stake their Gauge tokens through Cove’s contracts. Users can use the veYFI boost that Cove owns, reaping the benefit of boosted dYFI emission, as well as compounding dYFI tokens for higher overall APY for each underlying Yearn V3 vault. Cove can perpetually increase their veYFI ownership over time and let any users stake their yearn v3 Gauge tokens through Cove. Additionally YFI holders who wish to gain without providing additional assets can also partake in Cove by converting their YFI for coveYFI tokens then staking coveYFI for any protocol rewards. ## Non-goals Portfolio management of multiple vaults # Proposed Implementation The smart contract system will consist of the following components: * **coveYFI**: Smart contract that receives YFI from users. Then YFI is sent to **YearnStakingDelegate**, which perpetually locks YFI for veYFI, increasing the protocol’s ownership for veYFI. Diagram Light Diagram Dark * **YearnStakingDelegate (a.k.a. YSD)**: Responsible for locking YFI for veYFI. Yearn gauge tokens be held in this contract in order to receive the benefit of ve boosting. Additionally this contract should be able to delegate their veYFI in Snapshot such that its able to vote for initial voting rounds. Initially, an internal multisig will control the votes until a community counsel is established. It should also take future DAO onchain voting mechanisms into consideration. The dYFI rewards given out by each gauge should be split into 4 potential destinations with configurable params by the protocol admin/DAO. * `IYearnStakingDelegate.RewardSplit` * treasury * Cannot be higher than 20%. Sends to the treasury multisig. * coveYfi * Sends to **RewardForwarder** associated with **ERC20RewardsGauge** for staking CoveYFI token. * user * Sends to **StakingDelegateRewards**, rewarding the depositors of the Yearn gauge token. * lock * Sends to SwapAndLock for redeeming dYFI to YFI then locking it for veYFI. * **GaugeRewardReceiver**: For each Gauge, YSD deploys a clone of **GaugeRewardReceiver** and sets it as the receiver of rewards for the emissions from the gauge. `YSD.harvest(gauge)` will call `GaugeRewardReceiver.harvest( address swapAndLock, address treasury, IYearnStakingDelegate.RewardSplit calldata rewardSplit )` which claims dYFI emission from the associated Gauge and distributes it based on the given RewardSplit. * **ERC20RewardsGauge**: Contract responsible for rewarding ERC20 depositors. Used for rewarding **CoveYFI** token holders. * **YSDRewardsGauge**: Contract resposible for rewarding Yearn Gauge tokens depositors. Earns dYFI and COVE as reward tokens. * **YearnGaugeStrategy:** 4626 contract that takes in a Yearn Gauge token as the asset. It will depositing them in YSD, earning dYFI emission. Claims the dYFI emission from **StakingDelegateRewards**. Relies on **DYfiRedeemer** to redeem the claimed dYFI for YFI. On harvest it swaps YFI to base asset, then to the vault, then to the gauge, and deposits it in YSD, increasing its pricePerShare. * **SwapAndLock**: Receives its portion of rewards from the **GaugeRewardReceiver**, holds the dYFI until it is redeemed for YFI by **DYfiRedeemer** contract. Locks any YFI it has for YSD. * **StakingDelegateRewards**: Modified version of StakingRewards contract that allows emitting single reward token to multiple staking tokens. In our use case, it will stream dYFI rewards received from multiple **GaugeRewardReceivers**, each corresponding to a Gauge, to the users who deposited their Gauge tokens to YSD. Distributes dYFI pro-rata to depositors. These are claimed periodically which is streamed over reward duration which is configurable by the DAO. * **DYfiRedeemer**: Redeems dYFI from users who approve the contract. Using Yearn’s Redemption contract and flashloaning ETH, we can effectively acquire YFI without needing to exchange the entire balance of dYFI. Anyone can call `DYfiRedeemer.massRedeem(address[], uint256[] dYfiAmounts)` which borrows the required ETH from a flash loan provider, takes dYFI tokens from the approvers, redeem them for YFI, sells some of the YFI to ETH via Curve using chainlink price adjusted with slippage for ETH flashloan payback, then returns the remaining YFI to the users who it took dYFI from. The slippage parameter is controlled by the DAO but limited by immutable max parameter such that sufficient YFI can be sold for the flash loan payment. Any extra ETH that is left due to slippage expectation is sent to the caller of `massRedeem()` to incentivize automation. Sequence Diagram * Anyone can trigger `YearnStakingDelegate.harvest(address gauge)` * Upon harvest, the associated GaugeRewardReceiver will claim any pending dYFI from the corresponding gauge, and the rewards are split 4 ways: * Treasury split (default 0%, max 20%): * dYFI transfer to treasury * CoveYFI split (default 0%): * dYFI transfer to RewardForwarder associated with ERC20RewardsGauge for staking CoveYFI. * User split (default 100%): * dYFI transfer to **StakingDelegateRewards** and calls `notifyRewardAmount()`, allowing Yearn Gauge token depositors to earn dYFI rewards. * Determine appropriate amount to emit based on depositors’ duration and the amounts. * Cove’s **YearnGaugeStrategy** contracts, which are depositors of YSD, can claim dYFI from **StakingDelegateRewards** to exchange it to their asset and re-deploy them, increasing the value per share. * Lock split (default 0%): * dYFI is transferred to **SwapAndLock** which have approved **DYfiRedeemer** for dYFI usage. * **DYfiRedeemer** takes dYFI from **SwapAndLock** and redeems for YFI, returns it to **SwapAndLock** * YFI sent to the YSD and locked for veYFI * Ideally, this split is determined to target the ideal split to achieve high boost via increasing veYFI holding, but also reward the users with higher than base rate they would get from using Yearn themselves Diagram Light Diagram Dark ## Gauge Reward Claiming Process Diagram ## Dependencies * Requires Yearn V3 vaults, veYFI, and dYFI to launch first. * Relies on Curve for swapping YFI → base asset of the gauge. * Relies on a flash loan provider (Balancer). * Relies on Yearn’s Redemption contract to be filled. # YearnRouter4626Ext Source: https://docs.cove.finance/technical/boosties/yearn-router # Intro The purpose of the **YearnRouter4626Ext** contract is to improve the UX of the protocol by removing approval or deposit transactions at different steps. For example, instead of users acquiring coveYFI, approving it, then staking it, they can simply use the **YearnRouter4626Ext** contract to batch the steps into 1 transaction. For this purpose, the router is permissionless and stateless. Furthermore Permit2 can be used for reducing needed approvals if the token does not support Permit. # Permit availability 1. ❌ YFI 2. ✅ coveYFI 3. ✅ Curve v2 factory LP token 4. ✅ Yearn Vault v2 5. ✅ Yearn Vault v3 6. ❌ Yearn Gauge 7. ✅ Cove Yearn Strategy (TokenizedStrategy) 8. ✅ Cove Reward Gauge (Auto compounding gauge, non-autocompounding gauge, coveYFI rewards gauge) 9. ❌ StakeDAO Gauge # How to build multicall for users The general structure of the multicall will look like this (Optional) User TX #0: `inputToken.approve(PERMIT2, MAX_UINT_256)` User TX #1: `router.multicall()` with below array as the calldata: \[ (Optional) `router.selfPermit()` `router.pullToken()` or `router.pullTokenWithPermit2()`, (Optional) `router.approve()`, `router.deposit()` / `router.redeemFromRouter`, (Optional) `router.approve()`, `router.deposit()` / `router.redeemFromRouter`, ] Router will pull the input token from the user, and deposit it for itself for intermediary vaults, and deposit for user for the last vault, transferring desired vault shares to the user. 1. Determine if the input token supports Permit. If not use permit2 1. Case if the input token supports Permit: 1. Request signature from the user wallet for Permit transfer. **Use the EXACT amount the user wishes to use, not the max amount**, as this could allow malicious actors to use the approval in the future. 2. Use this signature as a param for `router.selfPermit()` call, build the calldata, and add to multicall() param array 3. Build the `router.pullToken()` calldata, and add to the multicall() param array 2. Case if the input token does NOT support Permit, use Permit2: 1. Check if the user has approved Permit2 1. `asset.allowance(address(user), address(PERMIT2)` 2. If not, request user to send an approval TX with the max amount so Permit2 can be used 1. `asset.approve(address(PERMIT2), type(uint256).max)` 3. Once the user has approved Permit2, build the `router.pullTokenWithPermit2()` calldata and add to the multicall() param array 2. Calculate expected shares minted / assets withdrawn via `preview*` functions 1. Build an array of input to output tokens as an array of addresses 2. Utilize `previewDeposit` or `previewRedeem` for calculating expected shares minted at each deposit step or expected assets received at each redeems. 3. Note that if the path contains a Yearn Vault v2, the estimation may not be accurate 3. Check if the router has enough approvals for each deposit step 1. For each step, check if allowance is enough 2. `asset.allowance(address(router), address(vault))` 3. If not, include `router.approve(asset, vault, MAX_UINT256)` calls before each deposits so that the Router is able to deposit successfully 4. (Note that this is a one-time approval for the first user to deposit into the vault via the router. We should not include unnecessary approvals for the users after) 5. For redeeming/withdrawing, where the input token is the vault, no approval is necessary 4. Simulate the `router.multicall()` with the params and check that expected return data at each step is correct. # Multicall call data examples ## Deposits ### LPToken → yVaultV2 → yvGauge → CoveYearnStrat → RewardsGauge Alice wishes to deposit 1e18 of her curve YFI/ETH LP token to cove’s auto-compounding gauge. Alice is the first user to use this path. Assume the `previewDeposit` call showed: 1e18 LP token → 0.9e18 Yearn Vault V2 → 0.9e18 Yearn Gauge → 0.8e18 CoveYearnStrategy → 0.8e18 AutoCompoundingRewardsGauge Frontend requests Permit signature for transferring the 1e18 LP token from Alice to the router and generates v, r, s. ```solidity router.multicall([ router.encodeFunctionData.selfPermit(LP_TOKEN, 1e18, deadline, v, r, s), router.encodeFunctionData.pullToken(LP_TOKEN, 1e18, address(router)), router.encodeFunctionData.approve(LP_TOKEN, YEARN_V2_VAULT, MAX_UINT256), router.encodeFunctionData.depositToVaultV2(YEARN_V2_VAULT, 1e18, address(router), 0.9e18), router.encodeFunctionData.approve(YEARN_V2_VAULT, YEARN_GAUGE, MAX_UINT256), router.encodeFunctionData.deposit(YEARN_GAUGE, 0.9e18, address(router), 0.9e18), router.encodeFunctionData.approve(YEARN_GAUGE, COVE_STRAT, MAX_UINT256), router.encodeFunctionData.deposit(COVE_STRAT, 0.9e18, address(router), 0.8e18), router.encodeFunctionData.approve(COVE_STRAT, REWARDS_GAUGE, MAX_UINT256), router.encodeFunctionData.deposit(REWARDS_GAUGE, 0.8e18, address(alice), 0.8e18), ]); ``` Ben hears about this opportunity and wants to replicate what Alice did but with 2e18 LP token. Assume the `previewDeposit` call showed: 1e18 LP token → 0.9e18 Yearn Vault V2 → 0.9e18 Yearn Gauge → 0.8e18 CoveYearnStrategy → 0.8e18 AutoCompoundingRewardsGauge Frontend requests Permit signature for transferring the 2e18 LP token from Ben to the router and generates v, r, s. ```solidity router.multicall([ router.encodeFunctionData.selfPermit(LP_TOKEN, 2e18, deadline, v, r, s), router.encodeFunctionData.pullToken(LP_TOKEN, 2e18, address(router)), router.encodeFunctionData.depositToVaultV2(YEARN_V2_VAULT, 2e18, address(router), 1.8e18), router.encodeFunctionData.deposit(YEARN_GAUGE, 1.8e18, address(router), 1.8e18), router.encodeFunctionData.deposit(COVE_STRAT, 1.8e18, address(router), 1.6e18), = router.encodeFunctionData.deposit(REWARDS_GAUGE, 1.6e18, address(ben), 1.6e18), ]); ``` ### yvGauge → CoveYearnStrat → RewardsGauge Alice already holds 0.9e18 yearn gauge tokens and wants to earn COVE token on top. ```solidity router.multicall([ router.encodeFunctionData.pullTokenWithPermit2(YEARN_GAUGE, 0.9e18, permit, transferDetails, signature), router.encodeFunctionData.approve(YEARN_GAUGE, COVE_STRAT, MAX_UINT256), router.encodeFunctionData.deposit(COVE_STRAT, 0.9e18, address(router), 0.8e18), router.encodeFunctionData.approve(COVE_STRAT, REWARDS_GAUGE, MAX_UINT256), router.encodeFunctionData.deposit(REWARDS_GAUGE, 0.8e18, address(alice), 0.8e18), ]); ``` ### stakeDaoGauge → yVaultV2 → yvGauge → CoveYearnStrat → RewardsGauge Alice already holds 0.9e18 stakeDaoGauge tokens and wants to move to Cove’s auto compounding gauge. **This is a special case where we must combine redeem and deposit calls together** ```solidity router.multicall([ router.encodeFunctionData.pullTokenWithPermit2(STAKE_DAO_GAUGE, 0.9e18, permit, transferDetails, signature), router.encodeFunctionData.redeemStakeDaoGauge(STAKE_DAO_GAUGE, 0.9e18), router.encodeFunctionData.approve(YEARN_V2_VAULT, YEARN_GAUGE, MAX_UINT256), router.encodeFunctionData.deposit(YEARN_GAUGE, 0.9e18, address(router), 0.9e18), router.encodeFunctionData.approve(YEARN_GAUGE, COVE_STRAT, MAX_UINT256), router.encodeFunctionData.deposit(COVE_STRAT, 0.9e18, address(router), 0.8e18), router.encodeFunctionData.approve(COVE_STRAT, REWARDS_GAUGE, MAX_UINT256), router.encodeFunctionData.deposit(REWARDS_GAUGE, 0.8e18, address(alice), 0.8e18), ]); ``` ### stakeDaoGauge → yVaultV2 → yvGauge → NonCompoundingRewardsGauge Alice already holds 0.9e18 stakeDaoGauge tokens and wants to move to cove’s non-auto compounding gauge. **This is a special case where we must combine redeem and deposit calls together** ```solidity router.multicall([ router.encodeFunctionData.pullTokenWithPermit2(STAKE_DAO_GAUGE, 0.9e18, permit, transferDetails, signature), router.encodeFunctionData.redeemStakeDaoGauge(STAKE_DAO_GAUGE, 0.9e18), router.encodeFunctionData.approve(YEARN_V2_VAULT, YEARN_GAUGE, MAX_UINT256), router.encodeFunctionData.deposit(YEARN_GAUGE, 0.9e18, address(router), 0.9e18), router.encodeFunctionData.approve(YEARN_GAUGE, NON_COMPOUNDING_REWARDS_GAUGE, MAX_UINT256), router.encodeFunctionData.deposit(NON_COMPOUNDING_REWARDS_GAUGE, 0.9e18, address(alice), 0.9e18), ]); ``` # Access Controls Source: https://docs.cove.finance/technical/cove/access-controls Access controls for Cove ## Entity–relationship model with roles Entity-relationship model ## Contracts The [community multisig](ecosystem/token/governance#community-multisig) controls `DEFAULT_ADMIN_ROLE` and `_TIMELOCK_ROLE` (via the [OpenZeppelin TimelockController contract](https://etherscan.io/address/0x705F82BB431fAdA1a0F11D7b77B3f0586c545CBc)). Other roles will be controlled by an ops multisig, EOAs for OpenZeppelin Defender keepers, and external strategists. ### BasketManager **Roles** | Role | Description | Privileges | Controlled By | | -------------------------- | --------------------------------------------------- | ------------------------------------------------------- | -------------------- | | `_MANAGER_ROLE` | Managers can create new baskets. | `createNewBasket`, `collectSwapFee` | `DEFAULT_ADMIN_ROLE` | | `_PAUSER_ROLE` | Can pause the contract. | `pause` | `DEFAULT_ADMIN_ROLE` | | `_REBALANCE_PROPOSER_ROLE` | Can propose a new rebalance. | `proposeRebalance` | `DEFAULT_ADMIN_ROLE` | | `_TOKENSWAP_PROPOSER_ROLE` | Can propose a new token swap. | `proposeTokenSwap` | `DEFAULT_ADMIN_ROLE` | | `_TOKENSWAP_EXECUTOR_ROLE` | Can execute a token swap. | `executeTokenSwap` | `DEFAULT_ADMIN_ROLE` | | `_TIMELOCK_ROLE` | Can set critical parameters like fees and adapters. | `setManagementFee`, `setSwapFee`, `setTokenSwapAdapter` | `_TIMELOCK_ROLE` | | `_BASKET_TOKEN_ROLE` | Role given to basket token contracts when created. | `proRataRedeem` | `DEFAULT_ADMIN_ROLE` | **Functions** | Function Name | Required Roles | Description | | --------------------- | -------------------------------------- | ---------------------------------------------------------------------------- | | `createNewBasket` | `_MANAGER_ROLE` | Creates a new basket token with the given parameters. | | `proposeRebalance` | `_REBALANCE_PROPOSER_ROLE` | Proposes a rebalance for the given baskets. | | `proposeTokenSwap` | `_TOKENSWAP_PROPOSER_ROLE` | Proposes internal and external trades for rebalancing baskets. | | `executeTokenSwap` | `_TOKENSWAP_EXECUTOR_ROLE` | Executes token swaps proposed in `proposeTokenSwap`. | | `setManagementFee` | `_TIMELOCK_ROLE` | Sets the management fee for a basket. | | `setSwapFee` | `_TIMELOCK_ROLE` | Sets the swap fee for the protocol. | | `setTokenSwapAdapter` | `_TIMELOCK_ROLE` | Sets the address of the TokenSwapAdapter contract. | | `pause` | `_PAUSER_ROLE` or `DEFAULT_ADMIN_ROLE` | Pauses the contract. | | `unpause` | `DEFAULT_ADMIN_ROLE` | Unpauses the contract. | | `collectSwapFee` | `_MANAGER_ROLE` | Claims the swap fee for a given asset and sends it to the protocol treasury. | **Notes** * The `_TIMELOCK_ROLE` is critical for setting parameters that affect the protocol's operation, such as fees and adapters. * `_BASKET_TOKEN_ROLE` is dynamically assigned to basket tokens during their creation, allowing them to call specific functions like `proRataRedeem`. ### BasketToken **Roles** | Role | Description | Privileges | Controlled By | | ----------------- | ------------------------------------------- | --------------------------------------------------------------------------------- | ------------- | | `_BASKET_MANAGER` | Role given to the associated BasketManager. | `fulfillDeposit`, `fulfillRedeem`, `fallbackRedeemTrigger`, `prepareForRebalance` | N/A | **Functions** | Function Name | Required Roles | Description | | ----------------------- | ----------------- | ---------------------------------------------------------- | | `fulfillDeposit` | `_BASKET_MANAGER` | Fulfills all pending deposit requests. | | `fulfillRedeem` | `_BASKET_MANAGER` | Fulfills all pending redeem requests. | | `fallbackRedeemTrigger` | `_BASKET_MANAGER` | Triggers fallback logic for failed redemption fulfillment. | | `prepareForRebalance` | `_BASKET_MANAGER` | Prepares the basket for rebalance by advancing the epoch. | **Notes** * The `_BASKET_MANAGER` role is only given to the BasketManager contract at the BasketToken creation, ensuring only the BasketManager contract can call critical functions during the rebalance cycle. * The contract uses a fallback mechanism for failed redemptions, which is triggered by the BasketManager. ### FeeCollector **Roles** | Role | Description | Privileges | Controlled By | | -------------------- | ----------------------------------------------- | ------------------------------------------------------ | -------------------- | | `DEFAULT_ADMIN_ROLE` | Admin role with full control over the contract. | `setProtocolTreasury`, `setSponsor`, `setSponsorSplit` | `DEFAULT_ADMIN_ROLE` | | `_BASKET_TOKEN_ROLE` | Role given to each BasketToken contract | `notifyHarvestFee` | `DEFAULT_ADMIN_ROLE` | **Functions** | Function Name | Required Roles | Description | | --------------------- | -------------------------------- | ---------------------------------------------------------------- | | `setProtocolTreasury` | `DEFAULT_ADMIN_ROLE` | Sets the protocol treasury address. | | `setSponsor` | `DEFAULT_ADMIN_ROLE` | Sets the sponsor for a given basket token. | | `setSponsorSplit` | `DEFAULT_ADMIN_ROLE` | Sets the sponsor fee split for a given basket token. | | `notifyHarvestFee` | `_BASKET_TOKEN_ROLE` | Notifies the FeeCollector of fees collected from a basket token. | | `claimSponsorFee` | `DEFAULT_ADMIN_ROLE` or Sponsor | Claims the sponsor fee for a given basket token. | | `claimTreasuryFee` | `DEFAULT_ADMIN_ROLE` or Treasury | Claims the treasury fee for a given basket token. | **Notes** * The `_BASKET_TOKEN_ROLE` is dynamically assigned by the BasketManager to basket tokens, allowing them to notify fees. * Only the protocol treasury or admin can claim treasury fees. ### AssetRegistry **Roles** | Role | Description | Privileges | Controlled By | | --------------- | ----------------------------------------------------- | ---------------------------- | -------------------- | | `_MANAGER_ROLE` | Role responsible for managing assets in the registry. | `addAsset`, `setAssetStatus` | `DEFAULT_ADMIN_ROLE` | **Functions** | Function Name | Required Roles | Description | | ---------------- | --------------- | -------------------------------------------- | | `addAsset` | `_MANAGER_ROLE` | Adds a new asset to the registry. | | `setAssetStatus` | `_MANAGER_ROLE` | Sets the status of an asset in the registry. | **Notes** * The `_MANAGER_ROLE` is critical for adding and managing assets in the registry. * The contract uses a bit flag system to represent enabled assets, which is updated dynamically based on asset status. ### StrategyRegistry **Roles** | Role | Description | Privileges | Controlled By | | ----------------------- | ----------------------------------------- | ----------------------------------------------- | -------------------- | | `DEFAULT_ADMIN_ROLE` | Admin role for managing the contract. | Can assign/revoke roles and manage strategies. | `DEFAULT_ADMIN_ROLE` | | `_WEIGHT_STRATEGY_ROLE` | Role given to approved weight strategies. | None (used for validation in `supportsBitFlag`) | `DEFAULT_ADMIN_ROLE` | **Functions** | Function Name | Required Roles | Description | | ----------------- | ---------------------------------------- | --------------------------------------------------------------- | | `supportsBitFlag` | None (validates `_WEIGHT_STRATEGY_ROLE`) | Checks if a given weight strategy supports a specific bit flag. | **Notes** * The `_WEIGHT_STRATEGY_ROLE` is used to validate weight strategies before calling their `supportsBitFlag` function. ### ManagedWeightStrategy **Roles** | Role | Description | Privileges | Controlled By | | -------------------- | ----------------------------------------------------------------------------------------------- | ------------------ | -------------------- | | `DEFAULT_ADMIN_ROLE` | Admin role responsible for assigning and revoking `_MANAGER_ROLE`. | | `DEFAULT_ADMIN_ROLE` | | `_MANAGER_ROLE` | Role responsible for managing assets and setting target weights for the assets in the strategy. | `setTargetWeights` | `DEFAULT_ADMIN_ROLE` | **Functions** | Function Name | Required Roles | Description | | ------------------ | --------------- | ---------------------------------------------------------- | | `setTargetWeights` | `_MANAGER_ROLE` | Sets the target weights for the assets for the next epoch. | **Notes** * The `_MANAGER_ROLE` is critical for setting target weights, which directly affect the strategy's behavior. * The contract uses a mapping to store target weights for each bit flag. # Forge Docs (mdbook) Source: https://docs.cove.finance/technical/cove/forge-docs # Cove RFC Source: https://docs.cove.finance/technical/cove/rfc Cove pairs off-chain intelligence with on-chain automation to deliver curated 1-click DeFi vaults that earn higher, risk-adjusted yield 24/7. ## Background Traditional automated market makers (AMMs) are not well suited for portfolio or index construction because they suffer from [loss-versus-rebalancing (LVR)](https://a16zcrypto.com/posts/article/lvr-quantifying-the-cost-of-providing-liquidity-to-automated-market-makers/) due to [toxic order flow](https://insights.deribit.com/market-research/toxic-flow-its-sources-and-counter-strategies/) (i.e. all trades execute at worse-than-market prices). > *"We found that for the 17 pools we analyzed, covering 43% of TVL and chosen by size, composite tokens and data availability, total fees earned since inception until the cut-off date was \$199.3m. We also found that the total IL suffered by LPs during this period was USD 260.1m, meaning that in aggregate those LPs would have been better off by USD 60.8m had they simply HODLd."* > > Stefan Loesch, Nate Hindman, Mark B Richardson, Nicholas Welch: "Impermanent Loss in Uniswap v3", 2021; [arXiv:2111.09192](http://arxiv.org/abs/2111.09192). > *"Thus, providing liquidity has become a game reserved for sophisticated players with the introduction of Uniswap V3, where retail traders do not stand a chance."* > > Lioba Heimbach, Eric Schertenleib, Roger Wattenhofer: "Risks and Returns of Uniswap V3 Liquidity Providers", 2022; [arXiv:2205.08904](http://arxiv.org/abs/2205.08904). DOI: [10.1145/3558535.3559772](https://dx.doi.org/10.1145/3558535.3559772). We propose an alternative solution that eliminates LVR and guarantees general intent level execution as a lower bound (e.g. CoW Swap). This document introduces the BasketManager contract, which handles protocol deposits/withdrawals/LP tokens, custodying user assets, and managing the rebalance lifecycle. Storing user assets in one contract provides two major advantages from economies of scale: optimized/cheaper rebalancing (at the protocol level vs. for each basket) and increased value capture from matching trades internally. ## Summary Cove functions as an intent aggregator for liquidity providers (LPs). Users express their intent by choosing a weight strategy and a combination of ERC-20/4626 tokens (represented as an LP token). These choices form a basket, such as Gauntlet-optimized yield strategy with sDAI/sFRAX, a market cap weighted index strategy with stETH/sfrxETH/yETH, or custom weights. This approach limits the number of options while allowing the protocol to aggregate deposits efficiently. The weight strategy determines the weights of each token in a basket. When the protocol rebalances, there is the potential for [coincidence of wants](https://en.wikipedia.org/wiki/Coincidence_of_wants) (CoW) to exist between baskets, like ring trades in [CoW Swap's batch auctions](https://docs.cow.fi/overview/coincidence-of-wants). Approximately maximizing the volume of CoWs given the current/target protocol level allocations is solvable off-chain with linear programming. When there are matches, trades execute without leaking value (i.e. no price impact/slippage/fees/MEV from accessing exogenous liquidity). External trades are routed through CoW Swap, which now supports programmatic orders including TWAP via their [Programatic Order Framework](https://blog.cow.fi/introducing-the-programmatic-order-framework-from-cow-protocol-088a14cb0375), to ensure the best execution and capture positive slippage. The protocol includes configurable/switchable fees for management and internal trades. To ensure safe rebalancing, BasketManager follows a sequence of proposing, executing, and finalizing a rebalance while temporarily pausing deposits and withdrawals for the affected baskets. As BasketManager pools assets for all Baskets, the rebalancing process considers each Basket's asset preferences and weight strategy. For example, when a new deposit arrives for a Basket with a limited token selection and a market cap weighted strategy, BasketManager deploys funds according to the respective weights, crediting the Basket for the new deposit without impacting other Baskets. Once the rebalance is complete, the tracked balances within BM are updated to reflect any changes resulting from swaps since the previous rebalance. ## Terminology 📄 Contract 👮 Permissioned Actor 🧑 Permissionless Actor * **Smart Contract - BasketManager 📄** * The BasketManager contract is the core component of the Cove protocol, responsible for managing user deposits, withdrawals, and LP tokens. It also handles the rebalancing process, custody of user assets, and execution of trades. By pooling assets from all baskets, BasketManager enables efficient rebalancing and increased value capture through internal trade matching. * **Smart Contract - BasketToken 📄** * Token representing BasketManager's user deposits. Each BasketToken is defined and created with immutable selection of assets that will be considered for allocating and a weight strategy which determines the weights of the selected assets. The maximum number of selected assets will be capped and configurable (e.g. start at 4 with a maximum of 8). * **Smart Contract - WeightStrategy 📄** * Contract that each Basket is linked to for determining asset weights. Each weight strategy contract is associated with a single weight proposer who controls weight updates. Weights define the proportions of assets within a basket. Multiple baskets with varying asset selections can use the same WeightStrategy, provided the WeightStrategy supports all assets chosen by each basket. * When a Basket is created, an WeightStrategy address must be supplied. * **Smart Contract - SwapAdapter 📄** * Adapters are modular contracts that are written to execute trades (e.g. via an aggregator or auction). BM can support both intent based aggregators and on-chain execution aggregators as long as their parameters/states are verifiable by BM. * Intent based aggregators that support smart contract signing via ERC-1271 are supported, such as CoW Swap. * A generic dutch auction adapter with a flash loan-like mechanism could be implemented such that any on-chain user-executable aggregator is compatible. This also allows for easy deployment to other chains or L2s. * Another adapter could be used to swap more efficiently between 4626 tokens with the same underlying assets, or for lossless conversions between assets like USDC\<>DAI using MakerDAO's PSM. * **Actor - Weight Proposer 👮/📄** * Actors responsible for updating their associated WeightStrategy contracts with the new weights for all baskets subscribed to it. * **Actor - Rebalance Proposer 👮/📄** * Role that initiates the rebalance lifecycle. * **Actor - TokenSwap Proposer 👮** * Calculates an optimized set of internal and external trades to execute in this rebalance and submits them to BasketManager. * **Actor - TokenSwap Executor 👮** * Role that submits the calldata required to execute the submitted external trades. * If the Basket's AggregatorAdapter is synchronous, TokenSwapProposer also executes the swaps. * **Actor - Rebalance Executor 🧑** * Permissionless role that completes an ongoing rebalance and advances the epoch. Checks on the progress of the current rebalance are made. ## External Assumptions * Dependent oracles do not report incorrect prices. * BasketManager does not have on-chain access to live quotes from aggregators. * We assume the confidence intervals given by Pyth Oracles are sufficient to use. An oracle registry will be managed by the DAO and individual Oracle wrappers can be deployed to support additional operations (aggregating, applying 4626's price per share, etc). * TokenSwapProposer uses the ideal exchange rates derived from on-chain oracles instead of live quotes when generating the list of internal and external trades. * RebalanceProposer will submit a set of internal and external trades that describes the changes in ALL baskets. * Assets in BM are high quality (e.g. USDT, USDC, sDAI, sFRAX, stETH, cbETH) - liquid with low volatility and minimal instances of depegging. * BasketManager is designed for standard ERC-20/4626 tokens, and is not concerned with the potential effects of rebasing or non-standard ERC-20/4626 implementations such as fee-on-transfer tokens. ## Entity–relationship model Entity-relationship model ## Rebalance lifecycle flowchart ```mermaid flowchart TD subgraph a["Propose Rebalance"] Q1(["Are we far from the target weights?"]) P["Pause and set proposal timeout"] R1["Revert"] end subgraph b["Propose TokenSwap"] Q2(["Token swaps achieve target weights?"]) Q3(["Token swaps only involve assets that each basket wishes to hold?"]) R2["Revert"] S["Settle internal trades, save external trades, and set execution timeout"] end subgraph c["Execute TokenSwap"] Q4(["Do the directions and sell amounts match saved external trades?"]) Q5(["Are minAmounts above absolute min return amounts?"]) Swap(["Emit events / Execute swap and update execution timeout"]) R3["Revert"] end subgraph d["Complete Rebalance"] Q6(["Has TokenSwap Proposal timed out?"]) Q7(["Have TokenSwap Executions timed out?"]) Q8(["Has retry limit been reached?"]) Apply["Settle the successful trades and apply new balances"] R4["Revert"] Retry["Retry the failed trades"] Finish["Invalidate/cancel the failed trades and unpause protocol"] end Q1 -- yes --> P Q1 -- no --> R1 a -. TokenSwap Proposer submits internal and external trades .-> b Q2 -- yes --> Q3 Q2 -- no --> R2 Q3 -- yes --> S Q3 -- no --> R2 b -. TokenSwap executor submits swap params .-> c Q4 -- yes --> Q5 Q4 -- no --> R3 Q5 -- yes --> Swap Q5 -- no --> R3 c -. User calls completeRebalance .-> d Q6 -- yes --> Q7 Q6 -- no --> R4 Q7 -- yes --> Apply Q7 -- no --> R4 Apply --> Q8 Q8 -- yes --> Finish Q8 -- no --> Retry d -. TokenSwap Proposer submits new internal and external trades .-> b ``` ## User actions flowchart ```mermaid stateDiagram-v2 state "Has Asset Tokens" as HasAssetTokensWithdraw state "Has Asset Tokens" as HasAssetTokensDeposit state "Has LP Tokens" as HasLPTokensWithdraw state "Has LP Tokens" as HasLPTokensDeposit state "Has Pending Deposit" as PendingDeposit state "Has Claimable LP" as HasClaimableLPDeposit state "Has Claimable LP" as HasClaimableLPWithdraw state "Has Pending Withdraw" as PendingWithdraw state "Has Claimable Assets" as ClaimableAssets state DepositFlow { %% [*] --> HasAssetTokensDeposit HasAssetTokensDeposit --> PendingDeposit: Request Deposit PendingDeposit --> HasClaimableLPDeposit: System - Fulfill Deposit HasClaimableLPDeposit --> HasLPTokensDeposit: Claim LP Tokens } state WithdrawFlow { %% [*] --> HasLPTokensWithdraw HasLPTokensWithdraw --> PendingWithdraw: Request Single-token Withdraw (Send LP Tokens) PendingWithdraw --> ClaimableAssets: System - Fulfill Withdraw ClaimableAssets --> HasAssetTokensWithdraw: Claim Asset Tokens PendingWithdraw --> HasClaimableLPWithdraw: System - Fail Withdraw HasClaimableLPWithdraw --> HasLPTokensWithdraw: Claim LP Tokens HasLPTokensWithdraw --> HasAssetTokensWithdraw: Request Multi-token Withdraw (Immediately Burns LP) } ``` ## Overview of the rebalancing sequence 1. Each **Weight Proposer** asynchronously updates any **WeightStrategy** instances that they manage. * Updates can be proposed until the rebalance starts. For resolvers that have not been updated since the last rebalance, the prior target weights will be reused. * If a Weight Strategy's methodology is difficult to prove or implement on-chain, the Weight Proposer for the strategy should be permissioned. * Permission * Only allowed addresses of each WeightStrategy can propose new basket weights. * Checks * The proposed weights only include values for the assets each basket is opted into. * The sum of proposed weights are equal to 1. * Weights of baskets managed by a different weight resolver cannot be modified. * Input: * Any necessary data to determine the new weights. * Output * Each **Weight Proposer** calls `WeightStrategy.setTargetWeights(uint256 bitFlag, uint256[] weights)` * Gas cost increases as the number of baskets increases * Piecemeal - Each rebalance proposer submits new weights for baskets of each allocation type 1. WeightStrategyA = Gauntlet Optimized 1. Basket A,B weights 2. WeightStrategyB = Seven Seas Capital Optimized 1. Basket C,D weights 3. WeightStrategyC = market cap weighted 1. Basket E weights 2. No external dependencies, can be called JIT to generate 3. Methodology for calculating market cap can be deployed on-chain (store 4626's totalAssets \[= totalSupply \* convertToAssets] \* assetValue) 2. **Rebalance Proposer (DAO)** calls `BasketManager.proposeRebalance()`. * Calculate the new total target token amounts based on each basket's target weight. * Permissions * Could be permissionless with threshold limits. * Checks * Reads each basket's current weight and target weight and then calculates the new protocol level state and measures the difference between the current/target states. * If the delta is less than some threshold, rebalance is not proposed. * $\sum_{i=1}^{n}\sum_{j=1}^{m} x_{ij} \ge L$ * If the time since the last rebalance is less than some threshold, the rebalance is not proposed. * If there are pending deposits or redeems, the rebalance is proposed. * Input: * None * Output: * During `BasketManager.proposeRebalance()` * Each basket's target weight is fetched from the WeightStrategy contract and stored as a hash in the BasketManager contract. 3. **TokenSwap Proposer (DAO)** calculates the optimal swap pairs to reach the target amounts of each basket and calls `BasketManager.proposeTokenSwap(Trade[] internalTrades, Trade[] externalTrades)` to submit all necessary swap amounts and the associated basket and target weight information. BasketManager performs minimal on-chain validation to ensure the inputs align with each basket's target weights. If more advanced validation is needed, the role can be assigned to a separate contract using [Axiom](https://www.axiom.xyz/), transforming the process from a variable to a fixed cost. * The optimal internal trades and external trades should be calculated off-chain first. * Permission * Limited since the internal and external trades need to be optimized before submission. * Checks * Check if the each trade's value change with slippage is within threshold (no apparent faulty swaps leading to value loss). * Check if the end state of baskets weights and protocol weight is within threshold. * Check if affected baskets include the tokens they are swapping from/to. * If possible, validate the methodology on chain. * Effects * Immediately settle all internal trades. * Store the external trades to be verified against swap params when executing the swaps at the next step. * For each external trade, the minimum of acceptable minAmounts is established with the exchange rate based on oracle prices of two assets multiplied by a slippage constant. * The constant that is applied for estimating price impact/slippage should be adjustable by the DAO. * Omit any external trades with low volume from being stored. The limit should be configurable by the DAO. * Input: * List of current token amounts. * List of target token amounts. * Output * Optimized set of internal trades and external trades to reach the target token amounts. * Calls `proposeTokenSwap(Trade[] internalTrades, Trade[] externalTrades)`. 4. **TokenSwap Executor** uses quotes from the relevant API and then calls `BasketManager.executeTokenSwap(externalTrades, bytes data)` where the data is optional information required for the current token swap adapter. * Determines quotes from off-chain API and submits the slippage adjusted swap params to BM. * Permissions * Permissioned with allowlist that can be toggled. * Can be permissionless with sufficient checks in TokenSwapAdapter. * Inputs: * External trades that are proposed by TokenSwap Proposer. * Outputs: * Calls `executeTokenSwap(externalTrades, bytes data)` where the data is optional information used by the current token swap adapter. * `externalTrades.minAmount` is checked against the oracle value. * If using CoWSwapAdapter: * `data` is not used. * `externalTrades.minAmount` is used to create a cowswap order. * If using GenericDutchAuctionAdapter: * start amount, decrement steps, step durations. * begin dutch auction with the given parameters. 5. If required, **TokenSwap Executor** submits orders to the off-chain API for execution (e.g. [CoW Swap API](https://api.cow.fi/docs/)). * Responsible for reading the stored orders from BM and submit them using off-chain API. * CoW Swap orders have unique IDs so once a trade is executed it can no longer be filled so replays or duplicate submissions are not problematic. * If BasketManager is configured with an on-chain aggregator such as 1inch, this step is not needed. * Inputs: * verifiedOrderHashes from BM contract storage and orders from emitted events. * Outputs: * Submits the orders to the CoW Swap API for execution. * Note that CowSwap will revert any orderHashes that fail ERC-1271's isValidSignature check. * [https://docs.cow.fi/tutorials/how-to-place-erc-1271-smart-contract-orders/good-after-time-gat-orders](https://docs.cow.fi/tutorials/how-to-place-erc-1271-smart-contract-orders/good-after-time-gat-orders) 6. **Rebalance Executors** calls `BasketManager.completeRebalance` , executing any checks and validations needed to complete the rebalance and advance the epoch. * Responsible for completing rebalances and advancing the epoch. * Permission * Can be permissionless with sufficient checks at BM level. * Checks: * If target weights are not met within a specified tolerance, the rebalance enters a retry state. The rebalance status is set back to `REBALANCE_PROPOSED` and the token swap proposal process is restarted, allowing for additional iterations to converge closer to the target weights. * Inputs: * Current token balances. * Status of each external trade. * Outputs: * Calls `completeRebalance()`. * Effects: * Claims and records the result of any external trade orders. * Updates the BasketManager's internal accounting to reflect each basket's new token balances after the trades have been executed. * Advances the epoch. ### Window timings and retries After each step, the 15-minute window is reset. If the proposer role doesn't call within the window, then anyone can call `completeRebalance` to exit the rebalance process. * `proposeRebalance` * Charges management fee and processes deposits for rebalancing baskets. * Determines target weights. * Opens a 15-minute window for `proposeTokenSwap`. * If proposer role doesn't call within the window, anyone can call `completeRebalance`. * `proposeTokenSwap` * Settles internal trades and checks minimum amounts for external trades against on-chain oracle values. * Prolongs the ongoing rebalance window by an additional 15 minutes to allow sufficient time for swap execution. * If not called within the window, anyone can call `completeRebalance`. * `executeTokenSwap` * Executes token swap with extra data if necessary. * After 15 minutes, anyone can call `completeRebalance`. * `completeRebalance` * Checks if the current basket weights are within a specified tolerance of the target weights. * If not, retries up to 3 times, resetting the state as if `proposeRebalance` was just called. * If pending redemptions can't be fulfilled (not enough base asset), basket tokens are notified of the failed rebalance and users must claim shares back. ## Sequence diagrams ### CoW Swap adapter ```mermaid sequenceDiagram participant RebalanceProposer as Rebalance Proposer participant BasketManagerSC as BasketManager (using CowSwapAdapter) participant CoWSwapAdapter as CoWSwap Adapter participant CoWSwapClone as CoWSwapClone participant TokenSwapProposer as TokenSwap Proposer participant CowSwapAPI as CoWSwap API participant TokenSwapExecutor as TokenSwap Executor participant RebalanceExecutor as Rebalance Executor %% Stage 1: Rebalance Proposal RebalanceProposer->>BasketManagerSC: proposeRebalance() activate BasketManagerSC BasketManagerSC->>BasketManagerSC: Validate target weights BasketManagerSC->>BasketManagerSC: Pause the protocol and start rebalance process deactivate BasketManagerSC loop Retry behavior TokenSwapProposer-->>BasketManagerSC: Read the current state of the baskets and their target weights TokenSwapProposer->>TokenSwapProposer: Determine optimized set of trades to reach target weights TokenSwapProposer->>BasketManagerSC: proposeTokenSwap(InternalTrade[], ExternalTrade[]) activate BasketManagerSC BasketManagerSC->>BasketManagerSC: Validate and immediately settle internal trades BasketManagerSC->>BasketManagerSC: Store external trades deactivate BasketManagerSC %% Stage 2: Token Swap Intent Proposal TokenSwapExecutor-->>BasketManagerSC: Read external trades BasketManagerSC-->>TokenSwapExecutor: Return external trades TokenSwapExecutor->>CowSwapAPI: Get quotes for token swaps activate CowSwapAPI CowSwapAPI-->>TokenSwapExecutor: Return quotes deactivate CowSwapAPI TokenSwapExecutor->>TokenSwapExecutor: Construct calldata based on quotes TokenSwapExecutor->>BasketManagerSC: executeTokenSwap(data) activate BasketManagerSC BasketManagerSC->>CoWSwapAdapter: delegatecall.executeTokenSwap(data) activate CoWSwapAdapter CoWSwapAdapter->>CoWSwapClone: Clone and initialize the swapper contract per swap activate CoWSwapClone CoWSwapClone->>CoWSwapClone: Decode, validate and emit events CoWSwapClone->>CoWSwapClone: Store orderUIDs/orderHashes CoWSwapClone->>CoWSwapAdapter: deactivate CoWSwapClone CoWSwapAdapter-->>BasketManagerSC: end delegatecall deactivate CoWSwapAdapter deactivate BasketManagerSC %% Stage 3: Token Swap Intent Execution TokenSwapExecutor-->>CoWSwapClone: Read orderHashes CoWSwapClone-->>TokenSwapExecutor: Return orderHashes TokenSwapExecutor->>CowSwapAPI: Submit orders for execution activate CowSwapAPI CowSwapAPI-->>CoWSwapClone: ERC1271.isValidSignature(hash, bytes) CoWSwapClone-->>CowSwapAPI: Signature verification and swap execution deactivate CowSwapAPI %% Stage 4: Complete Rebalance RebalanceExecutor->>BasketManagerSC: completeRebalance() activate BasketManagerSC BasketManagerSC->>BasketManagerSC: Check and update external trades status end BasketManagerSC->>BasketManagerSC: Complete rebalance as-is if the retry limit has been reached deactivate BasketManagerSC ``` ### Generic dutch auction adapter ```mermaid sequenceDiagram participant RebalanceProposer as Rebalance Proposer participant BasketManagerSC as BasketManager (using aggregator adapter) participant GenericDutchAuctionAdapter as GenericDutchAuctionAdapter participant AuctionParticipant as Auction Participant participant inchAggregator as ex. 1inch Aggregator participant TokenSwapProposer as TokenSwap Proposer participant TokenSwapExecutor as TokenSwap Executor participant RebalanceExecutor as Rebalance Executor %% Stage 1: Rebalance Proposal RebalanceProposer->>BasketManagerSC: proposeRebalance() activate BasketManagerSC BasketManagerSC->>BasketManagerSC: Validate target weights BasketManagerSC->>BasketManagerSC: Pause the protocol and start rebalance process deactivate BasketManagerSC loop Retry behavior TokenSwapProposer-->>BasketManagerSC: Read the current state of the baskets and their target weights TokenSwapProposer->>TokenSwapProposer: Determine optimized set of trades to reach target weights TokenSwapProposer->>BasketManagerSC: proposeTokenSwap(InternalTrade[], ExternalTrade[]) activate BasketManagerSC BasketManagerSC->>BasketManagerSC: Validate and immediately settle internal trades BasketManagerSC->>BasketManagerSC: Store external trades deactivate BasketManagerSC %% Stage 2: Token Swap Intent Proposal TokenSwapExecutor-->>BasketManagerSC: Read external trades BasketManagerSC-->>TokenSwapExecutor: Return external trades TokenSwapExecutor->>BasketManagerSC: executeTokenSwap(data) activate BasketManagerSC BasketManagerSC->>GenericDutchAuctionAdapter: delegatecall.executeTokenSwap(data) activate GenericDutchAuctionAdapter GenericDutchAuctionAdapter->>GenericDutchAuctionAdapter: Parse data and opens a dutch auction per trade GenericDutchAuctionAdapter->>BasketManagerSC: end delegatecall deactivate GenericDutchAuctionAdapter deactivate BasketManagerSC %% Stage 3: Token Swap Execution AuctionParticipant->>BasketManagerSC: dutchAuctionLoan(auctionData, callbackCalldata) activate BasketManagerSC BasketManagerSC->>GenericDutchAuctionAdapter: delegatecall activate GenericDutchAuctionAdapter GenericDutchAuctionAdapter->>AuctionParticipant: executeOperation(auctionData, callbackCalldata) activate AuctionParticipant AuctionParticipant ->> inchAggregator: Execute trade inchAggregator ->> AuctionParticipant: AuctionParticipant->>GenericDutchAuctionAdapter: Transfer token auctioned for deactivate AuctionParticipant GenericDutchAuctionAdapter ->> GenericDutchAuctionAdapter: Validate against auction conditions GenericDutchAuctionAdapter->>BasketManagerSC: end delegatecall deactivate GenericDutchAuctionAdapter deactivate BasketManagerSC %% Stage 4: Complete Rebalance RebalanceExecutor->>BasketManagerSC: completeRebalance() activate BasketManagerSC BasketManagerSC->>BasketManagerSC: Check and update external trades status end BasketManagerSC->>BasketManagerSC: Complete rebalance as-is if the retry limit has been reached deactivate BasketManagerSC ``` ## Basket actions ### Creating a new Basket Baskets are specified by their: 1. Combination of assets to be considered in the allocation. 2. Address of the weight strategy contract The Basket is then deployed using `keccak256(uint256 selectionBitFlag, address weightStrategy)` as the salt, preventing duplicate deployments of the same config. Creation of new basket is permissioned. ### Deposit/Mint Deposits will be asynchronous and will be fulfilled at the start of each rebalance. Users can claim their shares after the next rebalance is finished. * Users call `requestDeposit` * This transfers the base asset to the BasketManager contract. * Protocol processes deposits at the next rebalance proposal, which transfers the base asset into the BasketManager, and credits the user's basket token contract with the corresponding shares. * After the rebalance is finished, users who requested deposit can now claim their shares by calling `deposit` or `mint` functions. ### Redeem Redeem will also be asynchronous if the user desires to receive the base asset only. Alternatively, we offer users to the ability to redeem basket tokens at any time for the their pro-rata allocation of the underlying tokens. 1. Synchronously * Users call `proRataRedeem` * Burn basket token from the user. * Transfer the currently allocated assets of the basket the user calculated pro-rata. * $q_{i} = BT_{burn} \times \frac{q_{i,total}}{B}$ * where $q_{i,total}$ is the total quantity of the i-th token in the basket, and $B$ is the total supply of basket tokens. * Users receive a set of tokens instead of the base asset. 2. Asynchronously * Users initiate the process by calling `requestRedeem`, which transfers their basket token shares and requests these shares to be burned in exchange for the base asset. * Redeems are processed at the conclusion of the next rebalance. If the basket manager successfully acquires sufficient base assets, it transfers the corresponding base asset to each basket token contract and burns the requested basket token shares. * If the rebalance fails, after its completion, the users can call `claimFallbackShares` to retrieve their previously requested basket token shares. * Users who previously called `requestRedeem` can then call `redeem` or `withdraw` on the respective basket token contract to claim the underlying assets. ### Update bitFlag The `BasketManager` contract allows the bitFlag of an existing basket to be updated through the `updateBitFlag` function. This function is restricted to only be callable by the `_TIMELOCK_ROLE`. To update a basket's bitFlag: 1. Call `updateBitFlag(address basket, uint256 bitFlag)` with the following parameters: * `basket`: The address of the basket token to update. * `bitFlag`: The new bitFlag value. It must be a superset of the current bitFlag. 2. The function will perform the following checks: * The `basket` must exist and be registered in `basketTokenToIndexPlusOne`. * The new `bitFlag` must be different from the current one. * The new `bitFlag` must be a superset of the current bitFlag, meaning it includes all the bits set in the current bitFlag. * The basket's strategy must support the new `bitFlag`. * The new `basketId` (hash of `bitFlag` and `strategy`) must not already exist to prevent duplicate baskets. 3. If all checks pass: * The old `basketId` mapping is removed and the new one is added to `basketIdToAddress`. * The `basketAssets` for the basket are updated based on the new `bitFlag`. * The `BasketBitFlagUpdated` event is emitted with the old and new bitFlag values and IDs. * The `bitFlag` is updated in the `BasketToken` contract. This process allows baskets to evolve over time by adding new assets while ensuring compatibility with the strategy and preventing duplicate baskets from being created. ## LP tokens Cove will use the [ERC-7540](https://eips.ethereum.org/EIPS/eip-7540) standard for LP tokens. Since this is an ERC20, Uniswap's [Permit2](https://github.com/Uniswap/permit2) will be compatible with the contract. ### Pricing LP tokens #### Problems Pricing the tokens of each Basket in terms of a single token is challenging because: 1. Each Basket can hold a diverse portfolio of assets. 2. The specific combination and quantities of assets held by a Basket can vary from one epoch to another due to rebalancing. This dynamic nature of a Basket's composition makes it difficult to determine a straightforward price for its tokens at any given point in time. #### Solutions * Use oracle prices of base asset combined with 4626's price per share: $$ {BP}_{i}= \frac{\sum_{j=1}^{n} (q_{j} \cdot O_{j} \cdot P_{j})}{S_{i}} $$ * $n$ = Number of different ERC-4626 tokens in the basket * $q_j$ = Quantity of the j\*-\*th ERC-4626 token in the basket * $O_j$ = Oracle price of the underlying asset of the j\*-\*th ERC-4626 token * $P_j$ = Price per share of the j\*-\*th ERC-4626 token in terms of the underlying asset * $S_{i}$ = Total supply of basket i * Does not reflect real value of basket tokens unless withdrawn pro-rata. #### Risks * This pricing will not account for execution costs for acquiring the assets thus relying on this could penalize depositors. * This value is generated at the time user views the call. ## Rebalancing optimization with linear programming ### Problem As number of baskets and available assets grows, it becomes not trivial to match intents. We will use linear programming to maximize the volume of internal trades. This minimizes losses (price impact/slippage) from accessing exogenous liquidity. ### Variables Let: * $B = \{b_1, b_2, \ldots, b_n\}$ be the set of baskets * $A = \{a_1, a_2, \ldots, a_m\}$ be the set of assets * $a_{U}$ be USDT * $IT = \{ (b_i, b_l, a_j, a_k) \mid b_i, b_l \in B, b_i \neq b_l, a_j, a_k \in A, a_j \neq a_k \}$ be the set of all possible internal trades between two different baskets * $ET = \{ (b_i, a_j, a_k) \mid b_i \in B, a_j, a_k \in A, a_j \neq a_k \}$ be the set of all possible external trades * $x_{ij}$ be the current holdings of asset $a_j$ in basket $b_i$ * $x_{ij}^*$ be the ideal target holdings of asset $a_j$ in basket $b_i$ * $T_{ijkl}$ be the internal trade variable representing the amount of asset $a_j$ to trade from basket $b_i$ for asset $a_k$ from basket $b_l$ * $E_{ijk}$ be the external trade variable representing the amount of asset $a_j$ to trade from basket $b_i$ to an external party for asset $a_k$ ### Determining Current Holdings This would be the balances of each asset including USDT that each basket is currently holding. The amount of USDT is the new user deposits that have accrued since the last rebalance process. ### Determining Target Holdings In order to determine the target holdings of assets, we need to account for users' deposit requests and redeem requests. First we calculate how much ideal amount of USDT will be withdrawn from the basket. (Note that this is only an estimation and would not account for fees/slippage. The real amounts we end up with will vary based on slippage of each trade pairs). Since we know the total supply of the basket token and the amount of basket tokens submitted by the users for redeeming, the below formulae would be used for the target holding amounts. * Let $V_i = \sum_{j=1}^{n}x_{ij} \cdot O_j \cdot P_j$ * USD value of basket i before rebalancing, including the pending USDT deposit. For the USDT target amount: $x_{iU}^* = \left( \frac{BT_{i}^{redeeming}}{\text{S}_i} \right) \times \dfrac{V_i - x_{iU}\cdot O_U}{O_U}$ For other assets' target amounts: ${x}_{ij}^* = \left( V_i - x_{iU}^* \cdot O_{U} \right) \times \frac{\text{target weight}_j}{1} / (O_j \cdot P_j)$ Then after the rebalancing is successful, the resulting balance of USDT will be claimable by redeem requesters. ### Objective Function The objective function balances the cost of internal and external trades, heavily penalizing the latter to encourage internal matches when possible. We aim to minimize the volume of external trades with a higher penalty: $$ \min Z = \alpha \sum_{(b_i, a_j, a_k) \in ET} E_{ijk} + \sum_{(b_i, b_l, a_j, a_k) \in IT} T_{ijkl} $$ where $\alpha$ is a large penalty constant for external trades (e.g., $\alpha = 1000000$). ### Constraints 1. **No Negative Holdings After Internal Trades:** For each basket $b_i$ and each asset $a_j$: $x_{ij} + \sum_{l=1, l \neq i}^{n} \sum_{k=1, k \neq j}^{m} (T_{ljik} - T_{ijkl}) \geq 0$ This ensures that no basket ends up with a negative quantity of any asset due to internal trades. 2. **External Trades Limited by Post-Internal Trade Balances:** For each basket $b_i$ and each asset $a_j$ : $\sum_{k=1, k \neq j}^{m} E_{ijk} \leq x_{ij} + \sum_{l=1, l \neq i}^{n} \sum_{k=1, k \neq j}^{m} (T_{ljik} - T_{ijkl})$ This ensures that any external trades are limited by the available balance of the asset in the basket after accounting for internal trades. 3. **Target Holdings Met After All Trades:** For each basket $b_i$ and each asset $a_j$ $x_{ij} + \sum_{l=1, l \neq i}^{n} \sum_{k=1, k \neq j}^{m} (T_{ljik} - T_{ijkl}) + \sum_{k=1, k \neq j}^{m} (E_{ijk} - E_{ikj}) \ge x_{ij}^*$ $x_{ij} + \sum_{l=1, l \neq i}^{n} \sum_{k=1, k \neq j}^{m} (T_{ljik} - T_{ijkl}) + \sum_{k=1, k \neq j}^{m} (E_{ijk} - E_{ikj}) \le (1 + \epsilon )\cdot x_{ij}^*$ This requires that the final holdings in each basket must match the target holdings after all trades have been completed. 4. **Trade Variables Non-Negative:** For all $T_{ijkl}$ and $E_{ijk}$: $T_{ijkl} \geq 0, \quad E_{ijk} \geq 0$ This ensures that all trade variables are non-negative, which is a standard requirement in trade optimization problems to prevent nonsensical negative trades. ### Verifiable Computation with Trusted Execution Environments (TEEs) The off-chain determination of optimal internal and external trades via linear programming introduces an element of trust. Participants in the Cove protocol rely on the TokenSwap Proposer to execute this complex computation faithfully and submit a genuinely optimized set of trades. While DAO governance provides a layer of oversight, the computational process itself remains opaque to external verifiers. Trusted Execution Environments (TEEs) offer a compelling solution to enhance the verifiability and integrity of this critical step. A TEE, such as Intel SGX or AMD SEV, provides a hardware-isolated environment within a processor where code and data can be protected against observation or tampering by the host system, including the operating system or hypervisor. **Benefits for Cove's Rebalancing Optimization:** 1. **Remote Attestation & Integrity**: The linear programming solver can be executed within a TEE. Crucially, TEEs support *remote attestation*, a process where the TEE cryptographically proves to a remote party (e.g., the BasketManager contract or users) that a specific, audited piece of software (the solver) was loaded and executed correctly within the secure enclave, and that the output (the proposed trades) is the genuine result of this computation. This provides strong integrity guarantees for the optimization process, ensuring the proposed trades haven't been manipulated. \[ZTEE] 2. **Reduced Trust Assumptions**: By leveraging TEEs, the protocol can significantly reduce the trust placed in the TokenSwap Proposer's operational security. Instead, trust shifts to the well-defined security properties of the TEE hardware and the attestation mechanism. This aligns with the broader DeFi ethos of minimizing reliance on trusted intermediaries. 3. **Confidentiality (Potential Future Enhancement)**: While the primary benefit here is verifiable execution, TEEs also offer confidentiality. If parts of the input data for the linear programming (e.g., very specific trading intentions beyond basket weights) were deemed highly sensitive in future iterations, TEEs could protect this data even from the host running the computation. 4. **Enhanced Transparency**: While the computation inside the TEE is a "black box" to the host, the remote attestation process makes the *choice of code* and the *integrity of its execution* transparent and verifiable. This is a step towards what the Flashbots article terms "Zero Trust Execution Environments," aiming to minimize trust dependencies. \[ZTEE] **Considerations:** Implementing TEE-based verifiable computation involves its own set of challenges, including the complexity of TEE application development, potential performance overheads (though likely acceptable for this off-chain process), and the inherent trust in the TEE hardware manufacturer and the key provisioning process. However, the substantial increase in verifiability and the reduction of trust in off-chain computation make TEEs a promising avenue for bolstering the security and trustworthiness of Cove's rebalancing mechanism. \[ZTEE] Flashbots. (2024-10-11). *Zero Trust Execution Environments*. [https://writings.flashbots.net/ZTEE](https://writings.flashbots.net/ZTEE) ## Calculating deposits and redeems * Let $V_i = \sum_{j=1}^{n}x_{ij} \cdot O_j \cdot P_j$ * USD value of basket i before rebalancing, including the pending USDT deposit. * Let $V_i^{*} = \sum_{j=1}^{n}x_{ij}^{*} \cdot O_j \cdot P_j$ * Ideal USD value of basket i, using ideal target balances for each token. * Let $V_i^{final} = \sum_{j=1}^{n}x_{ij}^{final} \cdot O_j \cdot P_j$ * Actual USD value of basket i after all trades are successfully executed. This will be less then the ideal target balances due to slippage/costs. First, the USDT that should be allocated for the requested redeems is calculated using the ideal exchange rate of the assets. Then we attempt to satisfy that the ideal USDT amount that should leave the basket. Then after the swaps are executed, for each basket, the amount to mint for deposits are determined by measuring the change of value of the basket * $BT_{i}^{minted} = (V_i^{final} - x_{i,USDT}^{final}\cdot O_{USDT}) - (V_i - x_{i, USDT} \cdot O_{USDT})$ * In case any of the trades associated with redemption fails, we replace the withdrawn value with the sum of value of the assets that will be withdrawn via `proRataRedeem` method. During a rebalance period where there are new deposits, the slippage associated with rebalancing will be paid by the depositors not the existing basket users. In the ideal scenario, the prices at the end of the rebalance will not deviate greatly from the the beginning of the rebalance. In the case that it does, we use the latest oracle price to determine the depositors value. ## Fees The protocol incorporates two types of fees: a configurable management fee for each basket and a global swap fee for internal trades. Both fees are measured in basis points (BPS) with a precision of 1e4. ### Management Fee The management fee is calculated based on the time elapsed since its last computation, which occurs at the start of every rebalance cycle and when users exit via pro-rata redemption. The fee is determined using the following formula: $fee = totalSupply \times managementFeeBps \times \frac{timeSinceLastHarvest}{(1e4 - managementFeeBps) \times 365 days}$ Where: * `totalSupply` is the current total supply of the basket token, excluding shares held by the fee collector or pending redemption. * `managementFeeBps` is the management fee in BPS for the specific basket. * `timeSinceLastHarvest` is the time elapsed since the last fee harvest. The calculated fee is minted as new shares to the fee collector contract. The `FeeCollector` contract then divides the fee between the protocol treasury and the strategy sponsor according to the configured split percentage for each basket. The `FeeCollector` contract will only use the `proRataRedeem` function for synchronous claiming of fees. This ensures that any tokens sent to the `FeeCollector` by other users will be ignored in the fee calculation, as the `proRataRedeem` function burns the shares immediately and transfers the underlying assets to the fee recipients. The `FeeCollector` will not use the asynchronous redemption process, which could potentially lead to claimable fallback shares being included in the total supply used for fee calculation. ### Swap Fee The swap fee is a global fee applied to all internal token swaps during rebalancing. It is charged on both the buy and sell tokens of each trade. The fee is calculated as follows: $feeOnSell = sellAmount \times \frac{swapFeeBps}{2e4}$ $feeOnBuy = buyAmount \times \frac{swapFeeBps}{2e4}$ Where: * `sellAmount` is the amount of the sell token being traded. * `buyAmount` is the amount of the buy token being received (before fee deduction). * `swapFeeBps` is the global swap fee in BPS. The swap fees are accumulated in the `BasketManager` contract for each token and can be claimed by the protocol admin, which transfers the collected fees to the protocol treasury. The swap fee is not further divided and goes entirely to the treasury. ### Maximum Fees The protocol enforces maximum values for both the management fee and swap fee to prevent excessive fees from being set. The maximum fees are as follows: | Fee Type | Maximum Value (BPS) | | -------------- | ------------------- | | Management Fee | 3,000 (30%) | | Swap Fee | 500 (5%) | Note that while the maximum values are set to 100%, it is expected that realistic fee values will be significantly lower to ensure the competitiveness and sustainability of the protocol. The management fee for each basket can be set individually by the protocol admin via the `setManagementFee` function in the `BasketManager` contract. The global swap fee can be set by the admin using the `setSwapFee` function in the same contract. Both functions enforce the respective maximum fee limits and can only be called by the protocol admin role. ## Oracles Cove employs oracles to value baskets and settle internal trades. The protocol is designed to support pluggable oracle implementations using [euler-price-oracle](https://github.com/euler-xyz/euler-price-oracle). ### Oracle Adapter Types Cove defines the following oracle adapter types: * **ERC-4626 Oracle**: Converts between an ERC-4626 vault's shares and its underlying asset using `convertToAssets` and `convertToShares`. This adapter is intended for use when no direct oracle exists for the vault token. * **Chained ERC-4626 Oracle**: Extends the ERC-4626 Oracle functionality to a chain of vaults (maximum depth of 10) until a target asset is reached, performing sequential conversions along the chain. * **Curve EMA Oracle (Underlying)**: Reads the Exponential Moving Average (EMA)-based pricing exposed by Curve Stable-Swap-NG pools. Configuration flags determine whether the pool's price is expressed in vault shares or underlying assets. ### Anchored Oracle Behaviour The `AnchoredOracle` implementation includes the following behaviors: * Automatic rescaling of the input amount if the primary quote is less than 1 WAD (i.e., `1e18`) to preserve precision. * Explicit `ScalingOverflow` revert on extreme input values. * The `maxDivergence` parameter is bounded between 0.1% and 50%; the constructor will revert if values outside this range are provided. ### Interface and Registration * Cove oracle adapters **must** conform to the **EIP-7726** (`IPriceOracle`) interface. * Oracle registration is managed via an `OracleRouter` contract, which is referenced by the `BasketManager`. Deployment scripts are responsible for the on-chain registration of each adapter. If an `AnchoredOracle` instance is used, its corresponding (primary, anchor) oracle pair must also be registered. The primary oracle implementation utilized is `AnchoredOracle`. This smart contract implements the `IPriceOracle` interface by retrieving quotes from a primary oracle and validating them against an anchor oracle. The primary quote must be within a specified divergence range from the anchor quote before the price is returned. This mechanism provides an additional layer of security against stale or manipulated oracle prices. For assets that cannot be priced directly in USD, a `CrossAdapter` is utilized with the base asset. ## Risks * Managers of each WeightStrategy's gas payment increases as the number of baskets grow. * Incorrect price calculation of a single asset could lead to incorrect accounting of the baskets. * If Cove is unable to complete swaps to facilitate withdrawals users will be required to withdraw their assets in-kind. ### Potential Griefing Attack via Pending Deposits/Redeems When users call `requestDeposit` or `requestRedeem`, the system ensures that the controller does not have any pending or claimable deposits or redeems from the controller's `lastDepositRequestId`. This behavior allows for a potential griefing attack: an attacker can call `requestDeposit` or `requestRedeem` with a minimal dust amount and specify the target controller address. As a result, the target controller would then be unable to make legitimate `requestDeposit` or `requestRedeem` requests until they first claim the pending request. **Recommendation for Integrators**: When integrating the `BasketToken` into other contracts, always check for any pending or claimable tokens before requesting a deposit or redeem. This ensures that any pending deposits or redeems are resolved, preventing such griefing attacks. ## Monitoring and Emergency Functionality Cove includes several features to monitor the system and respond to emergencies: ### Protocol and Asset Level Pausing The protocol allows for pausing at both the protocol and asset level. When paused, all baskets that contain the paused asset will be affected, but pro-rata withdrawals are still allowed. This functionality is implemented in the `BasketManager` contract. ### Off-Chain Keepers for Oracle Price Monitoring Off-chain keepers, such as OpenZeppelin Defender, will be used to monitor oracle prices in real-time. For example, if the price of USDT falls below 0.99, the keeper can automatically pause the protocol to prevent further issues. ### Real-Time Anomaly Detection Protocols/Services Cove plans to integrate with real-time anomaly detection protocols and services, such as [Forta](https://forta.org/), which can help identify and respond to potential threats or unusual activity within the protocol. These services can monitor for a wide range of issues, including: * Unexpected changes in asset prices * Large or suspicious transactions * Unauthorized access attempts * Smart contract vulnerabilities By leveraging these monitoring and emergency response features, Cove can quickly identify and mitigate potential risks, ensuring the safety and security of users' funds. ## Alternatives considered * Rebalancing methods * Auctions * The problem with auction mechanisms for frequent rebalancing is as follows (from [Aera V1 Weight Update](https://docs.aera.finance/v1-archive/concepts/vault-guardian/weight-update)): * Auctions are overly sensitive to current market price, * Auctions restrict participation to larger pools of capital and infrastructure to identify and participate in the auction. * The main advantage from using an auction mechanism like Kuiper is removing the oracle dependency. However, that dependency is already implicit since oracles are used to value basket tokens. In theory, CoW Swap should offer better execution due to ring trades, and by outsourcing this functionality we can reduce the complexity of the protocol and tap into CoW Swap's existing network of solvers. Cove will also support using dutch auctions to rebalance via an adapter as a fallback. * Existing work * Kuiper (oracle-less) - [https://kuiper.gitbook.io/kuiper-docs/protocol/rebalancing-auctions](https://kuiper.gitbook.io/kuiper-docs/protocol/rebalancing-auctions) * Set (uses MakerDAO price feeds) - [https://help.tokensets.com/en/articles/3399436-how-to-participate-in-set-protocol-rebalance-auctions](https://help.tokensets.com/en/articles/3399436-how-to-participate-in-set-protocol-rebalance-auctions) * [Balancer's Managed Pools](https://docs.balancer.fi/concepts/pools/managed.html) ([Aera V1](https://docs.aera.finance/v1-archive/concepts/aera-vault/balancer-managed-pool)) * While it retains some benefits of TWAP'ing, still suffers from loss-versus-rebalancing. * Omitting contract events and using shadow events for gas optimization ([Shadow](https://www.shadow.xyz/)) * Seems like a premature optimization given how much tooling relies on events. ## Related work * [Kuiper](https://kuiper.gitbook.io/kuiper-docs/) * [Tokemak's Autopilot v2](https://medium.com/tokemak/tokemak-v2-introducing-lmps-autopilot-and-the-dao-liquidity-marketplace-86b8ec0656a) * [Gauntlet's Aera v2](https://docs.aera.finance/how-aera-v2-works) * [Definitive](https://docs.definitive.fi/) * [Set](https://www.tokensets.com/) * [Sandclock](https://www.sandclock.org/) * [SUClave](https://github.com/getclave/suclave-ethglobal-istanbul/) * [Indexed Finance](https://indexed.finance/) ## Acknowledgements Special thanks to Joey Santoro (Variant), Tarun Chitra (Gauntlet), Ken Deeter (Electric), Saneel Srini (Accomplice), Peteris Erins (Auditless/Aera), Elliot Friedman (Solidity Labs), Storm Slivkoff (Paradigm), and Will Price for their feedback after reviewing drafts.