Platform: Code4rena
Start Date: 28/01/2022
End Date: 30/01/2022
Period: 3 days
Status: Completed
Reporters: liveactionllama, CloudEllie
Pot Size: $30,000 USDC
Participants: 22
Reporters: liveactionllama, CloudEllie
Judge: GalloDaSballo
Id: 80
League: ETH
leastwood | 1/22 | $12,844.92 | 3 | 2 | 1 | 1 | 0 | 0 | 0 | 0 |
kenzo | 2/22 | $5,796.20 | 3 | 1 | 0 | 1 | 0 | - | 0 | 0 |
WatchPug | 3/22 | $3,010.91 | 4 | 0 | 0 | 2 | 1 | - | - | 0 |
Dravee | 4/22 | $1,094.68 | 2 | 0 | 0 | 0 | 0 | - | - | 0 |
sirhashalot | 5/22 | $1,045.22 | 3 | 0 | 0 | 1 | 0 | - | - | 0 |
pants | 6/22 | $881.09 | 1 | 0 | 0 | 0 | 0 | - | 0 | 0 |
GeekyLumberjack | 7/22 | $881.09 | 1 | 0 | 0 | 0 | 0 | - | 0 | 0 |
robee | 8/22 | $213.59 | 2 | 0 | 0 | 0 | 0 | - | - | 0 |
TomFrenchBlockchain | 9/22 | $195.46 | 2 | 0 | 0 | 1 | 0 | 0 | - | 0 |
throttle | 10/22 | $167.73 | 3 | 0 | 0 | 1 | 0 | - | - | 0 |
Auditor per page
Yield v2 is a collateralized debt engine paired with a custom automated market maker, using a novel transaction building pattern.
We intend to allow our users to use their Convex tokens as a collateral and to claim the rewards for staking the Convex token with Convex finance accrued by those tokens, while deposited as collateral.
Abracadabra provides a similar facility which we have updated to use our dependencies, including a solidity compiler update from 0.6.12 to 0.8.6. Then that contract was extended through inheritance with the new functionality that is needed for integration with the Yield Protocol.
There are 4 smart contracts and 1 library in scope:
A Ladle module that allows Ladle batches to include calls to add or remove vaults from the ConvexYieldWrapper registry.
A wrapper contract for convex tokens that stakes them on the user's behalf, allowing them to claim rewards. This is an adapted convex wrapper contract upgraded to use solidity 0.8.6 and the standard Yield Protocol dependencies.
A wrapper contract inheriting from ConvexStakingWrapper that calculates an aggregated user balance from the all vaults owned by the same account in the Cauldron.
An oracle contract that provides a 3CRV/ETH price feed conforming to the interface and patterns from the audited Yield Oracles.
A library used to calculate the amount of Convex to mint from a given amount of Curve. This is an adapted CvxMining library contract upgraded to use solidity 0.8.6.
For a generic token to be used as a collateral, Yield protocol requires them to be transferred to a dedicated Join contract and then perform a depositing and borrowing action. This is all orchestrated through the Ladle is a batch of at least three steps.
Similarly, the repayment of debt is done in a batch through the Ladle.
To enable Convex as a collateral we need to wrap it in an ERC20 that stakes it and keeps track of who was the original owner of the Convex tokens, which vaults do they own in the yield Protocol, and the rewards that are owed at each point in time.
The ConvexYieldWrapper
contract includes addVault
and removeVault
functions to allow it to keep a lazily updated list of vaults that are owned by a given user. The ConvexModule
contract adds the functionality to the Ladle to call these functions via the addModule
and moduleCall
functions in the Ladle. This integration mode is required so that the vaultId can be known in the same transaction that is created.
As a further explanation for this, vaultIds are not deterministic and it is not possible to know them in advance. To be able to include in batches vaults that have been created in the same transaction, zero can be passed as the vaultId
and the Ladle will use a vault created in the same batch, if it exists. Since this cached vaultId resides in the LadleStorage for the duration of a transaction, it can be accessed by modules.
Therefore, to borrow with Convex collateral, staking it in the process, the user will execute through the Ladle a batch like follows:
To repay a debt and withdraw Convex collateral, unstaking it in the process, the user will execute this batch through the Ladle:
To facilitate audit the original ConvexStakingWrapper has maintained the existing functionality, and all changes are limited to upgrades to integrate it with our codebase. New features are implemented in the ConvexYieldWrapper that inherits from it.
All governance actions in the Yield Protocol are previously tested in blockchain forks and go through several layers of verification before committing them to the mainnet. Any check in smart contracts to verify that a governance change doesn't contain an error is considered superfluous.
Users are not expected to interact directly with the smart contracts, and it is accepted that they might suffer a loss by doing so. The smart contracts must be interacted with in very specific ways, usually by batching a number of calls in the same transaction. Recipes for borrowing and repaying debt have been included in this README, although other recipes exist and will be created in the future.
The recipes for safe interaction are implemented in our approved frontends. Interacting with the smart contracts using an unapproved frontend might lead to a loss of assets and users are not advised to do so.
However, what is never to be expected is that one user interacting with the smart contracts in any way could cause a loss for a different user.
The design of vault addition and removal is intended so that the vault registry in the ConvexYieldWrapper can be updated by anyone. An update should only benefit an account, and never represent a loss for the caller or the vault owner. Losses to an account caused by that same account failing to add or remove a vault when appropriate are accepted.
Cvx3CrvOracle._peek()
isContract
or some other means.Cvx3CrvOracle.sol
, peek()
and get()
both point to the same internal fn _peek()
, however get()
is transactional. This is all done intentionally to emulate behavior of Yield oracles.I
to represent integral to be consistent with the contracts these were based on.