Skip to content

Latest commit

 

History

History
95 lines (76 loc) · 5.99 KB

File metadata and controls

95 lines (76 loc) · 5.99 KB

Rate Provider: PriceFeed

Details

Context

Affine ultraLRTs are Symbiotic and Eigenlayer Liquid Restaking Tokens (LRTs). Affine UltraLRT vaults expose an exchange rate of affine vault share <-> affine vault asset via a rate provider. The approach to computing the rate is based on an totalAssets / totalShares approach.

Review Checklist: Bare Minimum Compatibility

Each of the items below represents an absolute requirement for the Rate Provider. If any of these is unchecked, the Rate Provider is unfit to use.

  • Implements the IRateProvider interface.
  • getRate returns an 18-decimal fixed point number (i.e., 1 == 1e18) regardless of underlying token decimals.

Review Checklist: Common Findings

Each of the items below represents a common red flag found in Rate Provider contracts.

If none of these is checked, then this might be a pretty great Rate Provider! If any of these is checked, we must thoroughly elaborate on the conditions that lead to the potential issue. Decision points are not binary; a Rate Provider can be safe despite these boxes being checked. A check simply indicates that thorough vetting is required in a specific area, and this vetting should be used to inform a holistic analysis of the Rate Provider.

Administrative Privileges

UltraEthS

UltraETH

Oracles

  • Price data is provided by an off-chain source (e.g., a Chainlink oracle, a multisig, or a network of nodes).

  • Price data is expected to be volatile (e.g., because it represents an open market price instead of a (mostly) monotonically increasing price).

Common Manipulation Vectors

  • The Rate Providers are susceptible to donation attacks.
    • comment: vaultAssets() uses a balanceOf.
    /**
     * @notice Get the total assets
     */
    function totalAssets() public view override returns (uint256) {
        return vaultAssets() + delegatorAssets - lockedProfit();
    }
    
    /**
     * @notice Get the vault liquid assets
     */
    function vaultAssets() public view returns (uint256) {
        return IERC20MetadataUpgradeable(asset()).balanceOf(address(this));
    }
    Part of the rate depends on the balance of the Vault's asset, which is a common occurrence.

Additional Findings

To save time, we do not bother pointing out low-severity/informational issues or gas optimizations (unless the gas usage is particularly egregious). Instead, we focus only on high- and medium-severity findings which materially impact the contract's functionality and could harm users.

Conclusion

Summary judgment: SAFE

These rate providers should work well with Balancer pools.