Centrifuge Protocol V3.1

The Centrifuge Protocol is an open, decentralized protocol for onchain asset management. Built on immutable smart contracts, it enables permissionless deployment of customizable tokenization products. Build a wide range of use cases, from permissioned funds to onchain loans, while enabling fast, secure deployment. ERC-4626 and ERC-7540 vaults allow seamless integration into DeFi. Using protocol-level chain abstraction, tokenization issuers access liquidity across any network, all managed from one Hub chain of their choice. The contest focuses on the v3.1 release, which adds onchain accounting, an improved multi-chain messaging system, a refactored core module that increases modularity, and more.
Details
Scope
Contest Results
On what chains are the smart contracts going to be deployed?
Ethereum, Base, Arbitrum, Avalanche, BNB Smart Chain, Plume
If you are integrating tokens, are you allowing only whitelisted tokens to work with the codebase or any complying with the standard? Are they assumed to have certain properties, e.g. be non-reentrant? Are there any types of weird tokens you want to integrate?
Protocol only supports standard tokens with 2-18 decimals (decimals are enforced in Spoke.sol contract), no weird tokens.
Are there any limitations on values set by admins (or other roles) in the codebase, including restrictions on array lengths?
Pool manager roles are fully trusted within the context of the pool. Pool manager roles include the hub manager, balance sheet manager, gateway manager, request manager, and hook manager.
Similarly, custom gateway adapters and transfer hooks should be able to do anything in their set pool (ie, trusted), but shouldn't be able to do anything outside of their pool, and can be considered untrusted (in the context of other pools).
Relayers on the on/off ramp manager are fully trusted to decide withdrawal destinations for assets in their pool.
Merkle proof manager strategists are fully trusted to execute calls allowed within the policy set for that pool.
Are there any limitations on values set by admins (or other roles) in protocols you integrate with, including restrictions on array lengths?
No.
Is the codebase expected to comply with any specific EIPs?
ERC-20: issued share tokens, as well as holdings on the balance sheet of a pool.
ERC-1404: standardized compliance checks for share tokens.
ERC-2612: permit functionality built in to share tokens.
ERC-4626: tokenized vault standard, used for synchronous deposit vaults.
ERC-6909: holdings of multi-tokens on the balance sheet of a pool.
ERC-7540: asynchronous vault standard, used for asynchronous vault logic.
ERC-7575: multi-asset vault standard, to allow multiple investment assets per share token.
Issues related to EIP non-compliance can be valid only if they lead to Medium or High impact, besides the EIP violation itself.
Are there any off-chain mechanisms involved in the protocol (e.g., keeper bots, arbitrage bots, etc.)? We assume these mechanisms will not misbehave, delay, or go offline unless otherwise specified.
There will be off-chain keepers for:
- Calling
notifyDeposit/notifyRedeemfor investor request claiming, based on the events from theBatchRequestManager. - Repaying underpaid transactions (e.g. price updates from
SimplePriceManager), based on events from theGateway. - Calling
QueueManager.sync, based on events from theBalanceSheet. - Calling
OnOfframpManager.deposit, based on transfers to the on/offramp manager contract.
What properties/invariants do you want to hold even if breaking them has a low/unknown impact?
-
Please discuss any design choices you made.
See docs, e.g.
- Cross-chain design: https://v3-1.documentation-569.pages.dev/developer/protocol/features/chain-abstraction/
- Modularity: https://v3-1.documentation-569.pages.dev/developer/protocol/features/modularity/
- Technical architecture: https://v3-1.documentation-569.pages.dev/developer/protocol/architecture/overview/
Please provide links to previous audits (if any) and all the known issues or acceptable risks.
Audits: https://v3-1.documentation-569.pages.dev/developer/protocol/security/
Known issues:
- Ability to manipulate prices of the SimplePriceManager if on/offramp manager or sync deposits are enabled is known (by depositing to raise assets) => it is up to the pool manager to manage this, e.g. by using max reserve.
- Prices computed in SimplePriceManager may be off if approve and issue or approve and revoke are called separately, as then assets and shares are imbalanced.
- SimplePriceManager.onUpdate may revert, when the ShareClassManager issuance is negative, due to a transfer of shares before a submitQueuedShares, blocking updating a holding value.
- Arbitrage in multi-asset pools is pool manager controlled.
- LayerZero executions on target chain can be front-run and forced to go into failed messages queue.
- Hub.createPool can be frontrun leading to griefing
- Any issue related to arbitrage between different assets/currencies in the same pool. Should be managed by pool manager
- Any arbitrage related to cross-chain price updates
- Issues related to cross-chain messages not being executed for a long time, in the wrong order or create race-conditions
- GasService estimate is under/overestimated.
- Subsidized funds can be spammed: we will add min investment limits to alleviate this.
- AsyncRequest._withdraw() using current pricePoolPerAsset which is potentially unlikely pricePoolPerAsset during approval of redemption
- Only deployed on chains with Cancun EVM support. And no zksync.
- After Root.relySchedule executes, the timelock does not apply anymore => intentional, combined with spell pattern it works
- Guardian only works with Safe, if the admin is not a Safe the pause can only be executed by the full Safe and not individual owners
- Liquidity can be stuck if a user is frozen
- Liquidity can be stuck if all vaults are unlinked
- While paused, users can still claim assets/shares
- Auth pattern does not check that there is at least 1 ward
- Manager needs to ensure hooks across domains are compatible
- User needs to ensure they transfer valid share tokens eg member
- Issues with underlying networks being compromised affecting the pools deployed on that network
- Missing existence checks in Hub for pool/sc/asset and other IDs
- Updating vault or request manager can cause loss of pending request state
Please list any relevant protocol resources.
Additional audit information.
Severity clarifications:
- The DOS-related issues can be considered High severity only if they lead to a permanent lock of funds without a way to retrieve/recover them. If the funds can be recovered and the DOS is only temporary, the issue can be Medium at most.
- Bypassing any hook check can be considered Medium-severity at most (if leads to Medium impact).
- Issues that lead to stealing or loss of native tokens stored in the RefundEscrow for gas can be Medium at most.
- Issues with underlying networks being compromised affecting the pools deployed on that network are out of scope.
- Issues that are caused by price manipulation (e.g. pool donations) can be Medium at most.
A particular area of concern is pool managers being able to manipulate other pools. Several issues have been found in the past related to this, including:
- A malicious adapter set as a pool adapter, creating a batch that has pool A (its own pool) as the first message, and pool B as the next message(s). Fixed by checking all messages in the batch have the same pool ID.
- A malicious vault factory being used to rely malicious vaults on the existing
AsyncRequestManager. Fixed by changing the rely flow.
The main changes in v3.1 versus v3.0.1 include:
- Separated
ShareClassManagerto a modularBatchRequestManager, andShareClassManagerwith only the share class logic - Simplified
Spokecontract, separateVaultRegistry - New
QueueManagerfor automating balance sheet synchronization to the hub - New
NAVManagerfor automating NAV calculations - New
SimplePriceManagerfor automating share price calculations based on the NAV - New
OracleValuationcontract for manual updates of asset prices - Support for
UpdateContractfrom spoke to hub - Refactored hooks to a
BaseTransferHookwith simplified implementations on top - Simplified gateway changes
- Separate protocol and ops guardian
- Gateway payment method has changed from subsidized to pay directly in call with full refunds, except for vaults which implements subsidized payments in the higher level contracts
Total Rewards
Contest Pool
Lead Senior Watson
Lead Judge
234,400 USDC
30,000 USDC
12,000 USDC
Status
Scope
Start Time
End Time
Judging Rules
Reserved Auditors