Platform: Code4rena
Start Date: 23/02/2024
Pot Size: $36,500 USDC
Total HM: 2
Participants: 39
Period: 7 days
Judge: Dravee
Id: 338
League: ETH
Rank: 4/39
Findings: 1
Award: $414.48
π Selected for report: 1
π Solo Findings: 0
π Selected for report: hunter_w3b
Also found by: 0xbrett8571, DarkTower, Myd, ZanyBonzy, aariiif
414.4831 USDC - $414.48
Spectra
ContestSpectra is a permissionless interest rate derivatives protocol for DeFi. It allows users to split the yield generated by an Interest Bearing Token (IBT) from the principal asset.
Key Features:
Benefits:
tokens
PrincipalToken.sol: The PrincipalToken
contract is an ERC-20 token that represents a principal token (PT) issued by a vault. The vault holds an Interest Bearing Token (IBT) of a specific underlying asset. PTs represent a claim on the underlying asset held by the vault, plus any yield generated by the IBT.
Key Features
Other Notable Features
YieldToken.sol: This contract allows users to hold and transfer tokens that represent their yield ownership. It integrates with a PT contract to track yield and ensure that yield is updated before any YT transfers. The contract is designed to work seamlessly with the PT contract, providing a comprehensive solution for managing yield and principal tokens.
Key Features
transfer
and transferFrom
functions to update the yield before any transfer. This ensures that users' yield ownership is maintained even after transfers.Benefits of Using a YT Contract:
proxy
AMBeacon.sol: The AMBeacon
contract, which is a modified version of the standard OpenZeppelin UpgradeableBeacon
contract. It is used in conjunction with proxy contracts to determine their implementation contract.
Key Features:
UpgradeableBeacon
contract, which uses the Ownable pattern for access control, the AMBeacon
contract uses the AccessManager contract from OpenZeppelin 5.0 for more granular access control.upgradeTo
function, which upgrades the beacon's implementation, is restricted to specific roles within the AccessManager contract.Benefits of Using AMBeacon:
AMBeacon
contract provides more granular control over who can upgrade the beacon's implementation.upgradeTo
function, making it suitable for various governance models.AMBeacon
contract simplifies the process of upgrading proxy contracts by providing a central point of control for the implementation.AMProxyAdmin.sol: The AMProxyAdmin
contract, which is a modified version of the standard OpenZeppelin ProxyAdmin
contract. It is used to manage the upgrades of transparent upgradeable proxies.
Key Features:
AMProxyAdmin
contract allows for the upgrade of transparent upgradeable proxies to new implementation contracts.ProxyAdmin
contract, which uses the Ownable pattern for access control, the AMProxyAdmin
contract uses the AccessManager contract from OpenZeppelin 5.0 for more granular access control.upgradeAndCall
function, which upgrades the proxy and calls a function on the new implementation, is restricted to specific roles within the AccessManager contract.Benefits of Using AMProxyAdmin:
AMProxyAdmin
contract provides more granular control over who can upgrade proxies.upgradeAndCall
function, making it suitable for various governance models.AMProxyAdmin
contract simplifies the process of upgrading proxies by providing a central point of control.AMTransparentUpgradeableProxy.sol: The AMTransparentUpgradeableProxy
contract, which is a modified version of the standard OpenZeppelin TransparentUpgradeableProxy
contract. It is used to create upgradeable transparent proxies that can be managed by a ProxyAdmin
contract.
Key Features:
TransparentUpgradeableProxy
contract, which uses the Ownable pattern for access control, the AMTransparentUpgradeableProxy
contract uses the AMProxyAdmin
contract from the same codebase for more granular access control.upgradeToAndCall
function, which upgrades the proxy and calls a function on the new implementation, is restricted to specific roles within the AMProxyAdmin
contract.Benefits of Using AMTransparentUpgradeableProxy:
AMProxyAdmin
contract for access control, the AMTransparentUpgradeableProxy
contract provides more granular control over who can upgrade the proxy.upgradeToAndCall
function, making it suitable for various governance models.AMTransparentUpgradeableProxy
contract simplifies the process of upgrading proxies by providing a central point of control.libraries
PrincipalTokenUtil.sol: The PrincipalTokenUtil
, is a library that provides utility functions for working with principal tokens. Principal tokens are ERC-4626
tokens that represent a share of an underlying asset, such as a stablecoin or a basket of assets.
Key Features:
Functions:
_convertToSharesWithRate
: Converts an amount of the underlying asset to an equivalent amount of principal token shares, using the specified exchange rate._convertToAssetsWithRate
: Converts an amount of principal token shares to an equivalent amount of the underlying asset, using the specified exchange rate._computeYield
: Computes the yield accrued by a user since the last update, considering changes in the exchange rates of the principal token and the underlying asset._tryGetTokenDecimals
: Attempts to fetch the token decimals for a given token address._computeTokenizationFee
: Computes the tokenization fee for a given amount, based on the fee rate stored in the registry contract._computeYieldFee
: Computes the yield fee for a given amount, based on the fee rate stored in the registry contract._computeFlashloanFee
: Computes the flashloan fee for a given amount, based on the fee rate stored in the registry contract.Benefits of Using PrincipalTokenUtil:
RayMath.sol: The RayMath
, is a library that provides functions for converting between different decimal representations and a fixed-point representation called "Ray." Ray is a fixed-point representation with 27 decimal places, and it is commonly used in decentralized finance (DeFi) applications to represent values such as exchange rates and asset prices.
Key Features:
fromRay
function allows for specifying whether the conversion should be rounded up or down to the nearest integer.toRay
function includes overflow protection to ensure that the conversion from a decimal representation to Ray does not result in an overflow.Functions:
_a
, uint256 _decimals
, bool _roundUp
): Converts a value from Ray to a specified number of decimal places, with the option to round up or down.Benefits of Using RayMath:
toRay
function includes overflow protection, ensuring that conversions from decimal representations to Ray do not result in overflows.Ethereum Mainnet
Roles in the Spectra protocol:
TransparentUpgradeableProxy
. The proxy admin has the authority to upgrade a proxy to a new implementation and optionally call a function on the new implementation._dispatchUpgradeToAndCall
function.PrincipalToken.sol: In PrincipalToken
, there are several roles defined through the usage of access control modifiers provided by the AccessManagedUpgradeable
contract. These roles include:
Admin Role: This role is typically assigned to the contract deployer or owner. It has the highest level of authority and can execute administrative functions such as pausing and unpausing the contract, changing the rewards proxy, and storing rates at expiry.
```solidity modifier restricted() { require(hasRole(ADMIN_ROLE, _msgSender()), "Restricted to admins"); _; } ```
Pausable Role: This role allows the account with this role to pause and unpause the contract.
```solidity /** @dev See {PausableUpgradeable-_pause}. */ function pause() external override restricted { _pause(); } /** @dev See {PausableUpgradeable-_unPause}. */ function unPause() external override restricted { _unpause(); } ```
Yield Claimer Role: This role has permissions to update and claim yield.
```solidity /** @dev See {IPrincipalToken-claimYield}. */ function claimYield(address _receiver) public override returns (uint256 yieldInAsset) { // ... } /** @dev See {IPrincipalToken-claimYieldInIBT}. */ function claimYieldInIBT(address _receiver) public override returns (uint256 yieldInIBT) { // ... } ```
Rewards Proxy Setter Role: This role is responsible for setting the rewards proxy contract address.
```solidity /** @dev See {IPrincipalToken-setRewardsProxy}. */ function setRewardsProxy(address _rewardsProxy) external restricted { // ... } ```
Flash Loan Role: This role enables the contract to perform flash loans.
```solidity /** * @dev See {IERC3156FlashLender-flashLoan}. */ function flashLoan( IERC3156FlashBorrower _receiver, address _token, uint256 _amount, bytes calldata _data ) external override returns (bool) { // ... } ```
These roles are implemented using the hasRole
function provided by OpenZeppelin's AccessControlUpgradeable
contract and are enforced through the restricted
modifier applied to various functions throughout the contract. Each of these roles grants specific permissions to perform certain actions within the contract, ensuring proper access control and security.
AMBeacon.sol:
Beacon Authority: This role is responsible for managing the upgrade process by changing the implementation contract that the beacon points to. The beacon authority can call the upgradeTo
function to upgrade the beacon to a new implementation. By default, the restricted
modifier ensures that only accounts with the appropriate role in the authority (typically the ADMIN_ROLE of the AccessManager contract) can perform upgrades. This role is assumed to be managed by an AccessManager contract.
Implementation Contract: While not explicitly defined within this contract, the beacon points to an implementation contract whose address is stored in the _implementation
variable. This contract is responsible for providing the logic that proxies will delegate function calls to. The beacon's upgradeTo
function allows changing the implementation contract to a new one, effectively upgrading the logic of proxies that rely on this beacon.
These two roles define the primary interactions and responsibilities within the contract.
AMProxyAdmin.sol:
TransparentUpgradeableProxy
. The proxy admin has the authority to upgrade a proxy to a new implementation and optionally call a function on the new implementation. The proxy admin role is restricted to accounts that have the appropriate role in the access manager contract, which is enforced by the restricted
modifier. The upgradeAndCall
function allows upgrading the proxy and calling a function on the new implementation, if required. The access control for this function ensures that only authorized accounts can perform upgrades and calls on the proxy.This role is managed by an access manager contract, and only accounts with the necessary permissions (typically assigned to specific roles like ADMIN_ROLE
) can perform proxy upgrades and function calls.
AMTransparentUpgradeableProxy.sol: In AMTransparentUpgradeableProxy
contract, the only role defined is that of the admin. The admin has the authority to upgrade the implementation of the proxy by calling the _dispatchUpgradeToAndCall
function. Other than the admin, there are no specific roles defined within this contract.
IBT rate is only updated upon user interactions with our protocol
PT rate is only updated after an accounted negative rate change on the IBT rate
PT and its YT should have an equal supply at all times
PT rate should not increase
ptRateOfUser(u) β₯ ptRate for all u in users with users being all the users that deposited in the PT.
Accounted IBT rate cannot decrease without impacting PT rate
If the protocol records an IBT rate decrease, the PT rate has to decrease to account for the negative rate.
Principal Token is ERC5095
All EIP-5095 invariants should hold such as previewRedeem β₯ redeem.
Principal Token deposit
Spectra
ProtocolAccordingly, I analyzed and audited the subject in the following steps;
Core Protocol Contract Overview:
I focused on thoroughly understanding the codebase and providing recommendations to improve its functionality.
The main goal was to take a close look at the important contracts and how they work together in the Spectra
protocol.
I start with the following contracts, which play crucial roles in the Spectra:
Main Contracts I Looked At
I start with the following contracts, which play crucial roles in the Spectra
:
PrincipalToken.sol YieldToken.sol AMBeacon.sol AMProxyAdmin.sol AMTransparentUpgradeableProxy.sol PrincipalTokenUtil.sol RayMath.sol
I started my analysis by examining the intricate structure and functionalities of the Spectra
protocol, which is a comprehensive suite of contracts that enables the creation and management of yield-bearing
tokens. The protocol consists of three main components: tokens, proxy contracts, and libraries. The tokens include the PrincipalToken
and YieldToken
, which represent the principal and yield components of a yield-bearing asset, respectively. The proxy contracts include the AMBeacon
, AMProxyAdmin
, and AMTransparentUpgradeableProxy
, which provide a flexible and secure mechanism for upgrading the implementation of the protocol's contracts. The libraries include the PrincipalTokenUtil
and RayMath
, which provide utility functions for working with principal tokens and fixed-point representations, respectively.
Documentation Review:
Then went to Review this docs for a more detailed and technical explanation of the Spectra
.
Compiling code and running provided tests:
Manuel Code Review In this phase, I initially conducted a line-by-line analysis, following that, I engaged in a comparison mode.
Line by Line Analysis: Pay close attention to the contract's intended functionality and compare it with its actual behavior on a line-by-line basis.
Comparison Mode: Compare the implementation of each function with established standards or existing implementations, focusing on the function names to identify any deviations.
Overall, I consider the quality of the Spectra
protocol codebase to be Good. The code appears to be mature and well-developed. We have noticed the implementation of various standards adhere to appropriately. Details are explained below:
Codebase Quality Categories | Comments |
---|---|
Architecture & Design | The protocol features a modular design, segregating functionality into distinct contracts (e.g., proxy, token, libraries) for clarity and ease of maintenance. The use of libraries like RayMath for mathematical operations also indicates thoughtful design choices aimed at optimizing contract performance and gas efficiency. |
Upgradeability & Flexibility | The project does implement upgradeability patterns (e.g., proxy contracts), which might impact long-term maintainability. Considering an upgrade path or versioning strategy could enhance the project's flexibility in addressing future requirements.. |
Error Handling & Input Validation | Functions check for conditions and validate inputs to prevent invalid operations, though the depth of validation (e.g., for edge cases transactions) would benefit from closer examination. |
Security Practices | The contracts demonstrate awareness of common security pitfalls in Solidity development. Functions are guarded with appropriate access control modifiers (e.g., onlyOwner , isAdmin checks), and state-changing functions are protected against reentrancy attacks. However, a comprehensive external security audit would be necessary to validate the absence of deeper vulnerabilities. |
Code Maintainability and Reliability | The provided contracts are well-structured, exhibiting a solid foundation for maintainability and reliability. Each contract serves a specific purpose within the ecosystem, following established patterns and standards. This adherence to best practices and standards ensures that the code is not only secure but also future-proof. The usage of contracts for implementing token and security features like access control further underscores the commitment to code quality and reliability. However, the centralized control present in the form of admin and owner privileges could pose risks to decentralization and trust in the long term. Implementing decentralized governance or considering upgradeability through proxy contracts could mitigate these risks and enhance overall reliability. |
Code Comments | The contracts are accompanied by comprehensive comments, facilitating an understanding of the functional logic and critical operations within the code. Functions are described purposefully, and complex sections are elucidated with comments to guide readers through the logic. Despite this, certain areas, particularly those involving intricate mechanics or tokenomics, could benefit from even more detailed commentary to ensure clarity and ease of understanding for developers new to the project or those auditing the code. |
Testing | The contracts exhibit a commendable level of test coverage, approaching nearly 100%, which is indicative of a robust testing regime. This coverage ensures that a wide array of functionalities and edge cases are tested, contributing to the reliability and security of the code. However, to further enhance the testing framework, the incorporation of fuzz testing and invariant testing is recommended. These testing methodologies can uncover deeper, systemic issues by simulating extreme conditions and verifying the invariants of the contract logic, thereby fortifying the codebase against unforeseen vulnerabilities. |
Code Structure and Formatting | The codebase benefits from a consistent structure and formatting, adhering to the stylistic conventions and best practices of Solidity programming. Logical grouping of functions and adherence to naming conventions contribute significantly to the readability and navigability of the code. While the current structure supports clarity, further modularization and separation of concerns could be achieved by breaking down complex contracts into smaller, more focused components. This approach would not only simplify individual contract logic but also facilitate easier updates and maintenance. |
Strengths | Among the notable strengths of the codebase are its adherence to innovative integration of blockchain technology. The utilization of libraries for security and standard compliance emphasizes a commitment to code safety and interoperability. The creative use of PrincipalTokenUtil.sol and RayMath.sol in the yields mechanics demonstrates. |
Documentation | The contracts themselves contain comments and some descriptions of functionality, which aids in understanding the immediate logic. It was learned that the project also provides external documentation. However, it has been mentioned that this documentation is somewhat outdated. For a project of this complexity and scope, keeping the documentation up-to-date is crucial for developer onboarding, security audits, and community engagement. Addressing the discrepancies between the current codebase and the documentation will be essential for ensuring that all stakeholders have a clear and accurate understanding of the system's architecture and functionalities. |
This is the core contract of Spectra. The Principal Token is EIP-5095 and EIP-2612 compliant. Users can deposit an EIP-4626 IBT or the underlying token of that IBT and receive Principal Tokens (PT) and Yield Tokens (YT). The PT contract holds the logic that separates the yield generated from the principal asset deposited in the IBT.
This contract represents the Yield Token (YT). The YT is an EIP-20 token and follows the EIP-2612 standard. The same amount of PT and YT is minted upon depositing into the protocol (PrincipalToken.deposit
, PrincipalToken.depositIBT
). The YT captures the yield generated by the deposited principal. Holding the YT allows the user to claim the corresponding amount of yield generated by the IBTs deposited in the associated PT contract.
The Spectra protocol uses the OpenZeppelin AccessManager to manage the access control of the different protected functions.
We thus modified the Openzepellin Transparent Proxy, Beacon Proxy and Proxy Admin of OpenZeppelin to leverage the access manager instead of the Ownable pattern for the upgrade and admin functions.
File Name | Core Functionality | Technical Characteristics | Importance and Management |
---|---|---|---|
PrincipalToken.sol | The PrincipalToken contract implements functionality for managing principal tokens, including depositing, withdrawing, redeeming, claiming fees and yields, and handling flash loans. | It utilizes various interfaces and libraries such as ERC20PermitUpgradeable , AccessManagedUpgradeable , ReentrancyGuardUpgradeable , PausableUpgradeable , IERC4626 , and IERC3156FlashBorrower . | The contract's functionality is crucial for managing principal tokens, ensuring secure and efficient operations through modifiers like notExpired , afterExpiry , and internal functions for conversions and rate calculations. Additionally, it handles fee claiming, yield updates, and flash loans while managing various state variables and emitting relevant events. |
YieldToken.sol | The Yield Token (YT) contract tracks users' yield ownership, minted in sync with Principal Tokens (PT). | It inherits from ERC20PermitUpgradeable, uses OpenZeppelin's Math library for arithmetic operations, and implements various functions for burning, minting, transferring, and checking balances. | It ensures accurate tracking of yield ownership, integrates with the associated PT contract for updates, and manages transfers while enforcing certain conditions through modifier-based validations. |
AMBeacon.sol | The AMBeacon contract facilitates the determination of implementation contracts for BeaconProxy instances, allowing dynamic upgrading of their functionality. | It inherits from AccessManaged for access control, utilizes the IBeacon interface, and emits events to signal implementation upgrades. | It enables secure and flexible contract upgrades by allowing only authorized parties to change the implementation address, managed through the Access Manager contract. |
AMProxyAdmin.sol | The AMProxyAdmin contract serves as an admin for TransparentUpgradeableProxy instances, facilitating their upgrading and function invocation. | It utilizes AccessManaged for access control, defines a version for the upgrade interface, and includes a function to upgrade and call a new implementation. | This contract ensures secure and controlled upgrading of proxy contracts, with access managed through the Access Manager contract. |
AMTransparentUpgradeableProxy.sol | The AMTransparentUpgradeableProxy contract implements a transparent upgradeable proxy pattern, allowing for upgradability of contracts while maintaining transparency. | It uses ERC1967Proxy as a base, employs a custom dispatch mechanism for upgrade and call functionality, and sets the admin during construction as an immutable variable. | This contract ensures secure and transparent upgrades of proxy contracts, with administrative control managed by an instance of ProxyAdmin, facilitating seamless transitions to new implementations. |
PrincipalTokenUtil.sol | The PrincipalTokenUtil library provides functions for converting assets to shares and vice versa, computing user yield, and fetching token decimals. | It uses math and rounding libraries for precise calculations, handles rate errors, and interacts with ERC20 token contracts to retrieve decimals. | This library plays a crucial role in managing tokenization fees, yield fees, and flashloan fees, ensuring accurate calculations and efficient fee management in token-related operations. |
RayMath.sol | The RayMath library provides functions for converting values between Ray (27-decimal precision) and specified decimal precisions. | It utilizes assembly code for efficient calculations, rounding options for precision control, and ensures integrity in value conversion. | This library is essential for precise arithmetic operations involving different decimal precisions, ensuring accurate conversions and calculations in decentralized finance (DeFi) applications. |
PrincipalToken.sol
Systemic Risks:
Flash Loan Vulnerabilities: The contract implements flash loan functionality, allowing users to borrow assets temporarily. Flash loan implementations can be susceptible to manipulation and abuse, leading to significant disruptions if exploited maliciously.
Price Oracle Dependency: The contract relies on external price oracles to determine exchange rates between assets. Inaccurate or manipulated price feeds can result in incorrect tokenization or redemption rates, leading to financial losses for users.
Centralization Risks:
restricted
modifier). Depending on the implementation and management of these privileged addresses, there's a risk of centralization where control over critical functions is concentrated in a few entities.Technical Risks:
flashLoan
function), which could introduce technical risks if not implemented securely. Flash loans are susceptible to various attacks such as reentrancy, front-running, and arbitrage if not properly handled.Integration Risks:
IERC4626
, IRewardsProxy
, IRegistry
, IERC3156FlashBorrower
, IERC3156FlashLender
, IERC20
) for various functionalities. Integration with external contracts introduces risks related to dependency on external systems, potential changes in interfaces, and unforeseen behavior of these external contracts.YieldToken.sol
Systemic Risks:
Dependence on Time: The balanceOf
function in the contract depends on the comparison of the current block timestamp with the maturity timestamp obtained from IPrincipalToken
. Any discrepancy or manipulation of time-related variables could lead to systemic risks by affecting the calculation of token balances.
Interconnectedness: This contract interacts with other contracts in the system, such as IPrincipalToken
. Changes or issues in these interconnected contracts could lead to systemic risks within the entire system.
Centralization Risks:
pt
which represents the associated principal token. If this token contract becomes compromised or inaccessible, it could impact the functionality of the YieldToken
contract, potentially leading to centralization risks.YieldToken
contract allows minting and burning functions to be called only by the principal token contract (pt
). This centralizes control over these critical operations to the principal token contract.Technical Risks:
Integration Risks:
openzeppelin-math
and openzeppelin-erc20-extensions
. Changes or updates to these external dependencies could lead to integration risks if they are not compatible with the existing codebase.YieldToken
contract implements various interfaces (IERC20
, IYieldToken
, ERC20Upgradeable
). Any inconsistencies or mismatches between the implementations of these interfaces could lead to integration issues with other parts of the system.AMBeacon.sol
Systemic Risks:
Upgrade Functionality: The upgradeTo
function allows the authority to change the implementation contract address, affecting all proxies that rely on this beacon. If this upgrade process is not properly managed or if the new implementation has vulnerabilities, it could lead to systemic risks affecting all contracts using this beacon.
Access Control: The contract relies on access control provided by AccessManaged
for managing authority roles. Any misconfiguration or unauthorized access to the upgrade functionality could lead to systemic risks, as it allows a single entity to control the upgrade process, potentially impacting the entire system.
Authority Control: The contract relies on a single authority, managed through AccessManaged
, to determine the implementation contract address. This centralized control could lead to centralization risks if the authority misuses its power or if there's a single point of failure in managing upgrades.
Implementation Validation: The _setImplementation
function checks if the provided newImplementation
address points to a valid contract by verifying its bytecode length. However, this check may not be comprehensive enough to ensure the security and reliability of the new implementation. Additional checks or audits may be necessary to mitigate technical risks associated with using unverified or potentially malicious implementations.
Proxy Integration: Contracts that rely on this beacon must properly integrate with it to ensure seamless upgrades and compatibility with the new implementations. Any issues in integrating with the beacon or handling upgrades could lead to integration risks, potentially disrupting the functionality of contracts using this beacon.
AMProxyAdmin.sol
Systemic Risks:
upgradeAndCall
function allows for upgrading the proxy to a new implementation and calling a function on the new implementation. If not properly secured or if the new implementation has vulnerabilities, this could introduce systemic risks, especially if sensitive or critical functions are called during the upgrade process.Centralization Risks:
AccessManaged
for controlling upgrader roles. This centralized control could lead to centralization risks if the authority misuses its power or if there's a single point of failure in managing upgrades.Technical Risks:
receive
function, indicating the possibility of using it during an upgrade if the second argument of upgradeAndCall
is an empty byte string. Depending on the implementation of the new contract, relying on the receive
function during upgrades might introduce technical risks, especially if it's not handled correctly.Integration Risks:
UPGRADE_INTERFACE_VERSION
). Depending on the compatibility of this version with existing contracts and tools, integration risks may arise if there are changes in the interface version that are not backward compatible. Developers integrating this contract need to ensure compatibility with the specified version.AMTransparentUpgradeableProxy.sol
Systemic Risks:
upgradeToAndCall
function enables upgrading the proxy to a new implementation and calling a function on the new implementation. If not properly secured or if the new implementation has vulnerabilities, this could introduce systemic risks, especially if sensitive or critical functions are called during the upgrade process.Centralization Risks:
AMProxyAdmin
, which is initially set during deployment and is immutable thereafter. This centralized control could lead to centralization risks if the admin account is compromised or misuses its power.Technical Risks:
Integration Risks:
PrincipalTokenUtil.sol
Systemic Risks:
_tryGetTokenDecimals
function attempts to fetch token decimals from the given token address. If this operation fails or returns unexpected results, it could lead to systemic risks, especially if other parts of the system rely on accurate token decimals for calculations.Centralization Risks:
IRegistry
) to fetch fee rates and other parameters. Centralization risks may arise if this registry contract is controlled by a single entity or has centralized governance, as changes to fee rates or other parameters could impact the entire system without sufficient decentralization.Technical Risks:
_computeYield
, _convertToSharesWithRate
, _convertToAssetsWithRate
) involve rate calculations (e.g., PT rates, IBT rates). Incorrect rate handling could lead to technical risks such as miscalculations, underflows, or overflows, potentially resulting in financial losses or unexpected behavior.Integration Risks:
RayMath.sol
Systemic Risks:
fromRay
function converts a value from Ray (27-decimal precision) to a representation with a specified number of decimals. Precision loss can occur during this conversion, especially if the target decimals are significantly lower than 27, leading to potential systemic risks in financial calculations.Centralization Risks:
RayMath
library is authored by a single entity ("Spectra"). Centralization risks may arise if maintenance or updates to this library are solely dependent on this single entity, potentially leading to bottlenecks or vulnerabilities if the entity becomes unavailable or unresponsive.Technical Risks:
fromRay
function includes a rounding mechanism based on the _roundUp
parameter. Incorrect rounding or edge cases not handled properly could lead to technical risks such as incorrect rounding behavior or unexpected results in financial calculations.Integration Risks:
RayMath
library for decimal conversions, any changes or updates to this library could potentially introduce integration risks. Changes in function signatures, logic, or behavior of the RayMath
library may require corresponding updates in dependent contracts to ensure compatibility and proper functioning.Dynamic Fee Structures: Implement dynamic fee structures that adjust based on market conditions, user activity, or other relevant factors. This flexibility can optimize revenue generation while ensuring competitive fees for users, ultimately enhancing protocol sustainability.
Liquidity Incentives: Introduce liquidity mining programs or yield farming incentives to attract liquidity providers and boost trading activity within the protocol. Rewarding users with tokens or other incentives can stimulate participation and foster a vibrant ecosystem.
Cross-Protocol Integrations: Explore opportunities for integrating with other DeFi protocols, such as decentralized exchanges (DEXs), lending platforms, or asset management protocols. Cross-protocol integrations can unlock new use cases, enhance liquidity, and create synergies between different DeFi ecosystems.
Risk Management Tools: Provide users with comprehensive risk management tools and analytics to assess and mitigate risks associated with yield farming, liquidity provision, and other activities. Empowering users with data-driven insights can help them make informed decisions and navigate volatile market conditions more effectively.
Community Governance: Transition towards a decentralized governance model where protocol decisions are made collectively by the community through governance tokens and voting mechanisms. Community governance fosters decentralization, transparency, and inclusivity, aligning the protocol's interests with those of its stakeholders.
Staking and Voting Rewards: Incentivize token holders to actively participate in governance and decision-making processes by offering staking rewards and voting incentives. Rewarding users for their engagement encourages active participation and strengthens the protocol's governance mechanisms.
Audits and Security Enhancements: Conduct regular security audits and implement robust security measures to protect user funds and safeguard the integrity of the protocol. Prioritize code reviews, bug bounties, and continuous monitoring to proactively identify and address potential vulnerabilities.
Yield-Bearing Tokens: Spectra introduces the concept of yield-bearing tokens (YT), which represent ownership of the yield generated by principal tokens (PT) deposited in the protocol. This innovative mechanism allows users to earn passive income from their deposited assets, enhancing the utility of their holdings.
Modular Architecture: The protocol's modular architecture enables seamless integration of new features and upgrades without disrupting existing functionality. By leveraging proxy contracts and libraries, Spectra ensures flexibility, extensibility, and maintainability, allowing for efficient protocol evolution over time.
Flash Loan Support: Spectra supports flash loans, allowing users to borrow assets temporarily without collateralization. This feature facilitates efficient capital deployment and arbitrage opportunities, enhancing liquidity and trading activity within the protocol.
Fee Customization: The protocol offers customizable fee structures for tokenization, yield claiming, and flash loans, empowering administrators to adjust fees based on market conditions and protocol requirements. This flexibility ensures sustainable revenue generation while maintaining competitiveness and user satisfaction.
Secure Mathematical Operations: Spectra incorporates the RayMath library for precise mathematical operations and conversions, ensuring accuracy and reliability in complex financial calculations. By using fixed-point arithmetic and overflow protection, the protocol minimizes errors and vulnerabilities, enhancing security and trustworthiness.
Decimals imprecisions should always benefit the protocol and no user should be able to extract extra value.
Proxy Admin and Beacon are a modified version of Openzepelin origin contract replacin OZ Ownable with OZ Access Managed. Check if this modification can be harmful outside of our trust model.
Imprecisions and rounding errors.
Manipulation of the IBT rate.
Mechanism of negative rates and the impact on the PT rate.
30 hours
#0 - c4-pre-sort
2024-03-03T14:04:56Z
gzeon-c4 marked the issue as high quality report
#1 - c4-pre-sort
2024-03-03T14:51:25Z
gzeon-c4 marked the issue as sufficient quality report
#2 - jeanchambras
2024-03-09T19:05:49Z
The report is of great quality. I noticed some confusion regarding the roles within the protocol. The risk assessment, although simplistic and possibly reused in part from past audits, is well-curated within the context of this audit.
#3 - c4-judge
2024-03-11T00:50:20Z
JustDravee marked the issue as grade-a
#4 - c4-judge
2024-03-11T01:58:34Z
JustDravee marked the issue as selected for report