Platform: Code4rena
Start Date: 01/09/2023
Pot Size: $36,500 USDC
Total HM: 4
Participants: 70
Period: 6 days
Judge: kirk-baird
Id: 281
League: ETH
Rank: 24/70
Findings: 2
Award: $262.16
๐ Selected for report: 1
๐ Solo Findings: 0
๐ Selected for report: adriro
Also found by: 0x6980, 0xStalin, 0xanmol, 0xmystery, 0xpanicError, Arz, Aymen0909, BenRai, Breeje, Lalanda, MohammedRizwan, Raihan, SovaSlava, Stormreckson, Udsen, ast3ros, bin2chen, castle_chain, catellatech, codegpt, dev0cloo, gkrastenov, hals, klau5, kutugu, ladboy233, matrix_0wl, nirlin, ohm, peanuts, pipidu83, sandy, wahedtalash77
7.08 USDC - $7.08
in the rUSDYFactory contract in the line 100 the devs used the assert instead of require or custom errors.
check the Solidity docs โก๏ธ https://docs.soliditylang.org/en/v0.8.19/control-structures.html#panic-via-assert-and-error-via-require
Please ckeck all the input addresses in the functions, constructor.
The onlyOwner
authority here is very important for some contracts, but the Ownable.sol library
imported with the import has the renounceOwnership() feature, in case the owner accidentally triggers this function, the remove functions will not work and the contract will block gas due to arrays, may have a continuous structure that exceeds its limit.
The solution to this is to overide and disable the renounceOwnership() function as implemented in many contracts in his project, it is important to include this code in the contracts.
function renounceOwnership() public payable override onlyOwner { revert("Cannot renounce ownership"); }
The Moonwell team makes use of Assembly on RWADynamicOracle contract, since this is a low level language that is more difficult to parse by readers, include extensive documentation, comments on the rationale behind its use, clearly explaining what each assembly instruction does.
This will make it easier for users to trust the code, for reviewers to validate the code, and for developers to build on or update the code.
Note that using Assembly removes several important security features of Solidity, which can make the code more insecure and more error-prone.
It is essential to clearly and comprehensively document all activities related to critical function assembly
within the project. By doing so, a more complete and accurate understanding of what is being done is provided, which is important both for auditors and for long-term project maintenance. By following the practices of monitoring and controlling project work, it can be ensured that all assemblies are properly documented in accordance with the project's objectives and goals.
In some contracts, certain things are described that do not match with what follows, for example:
DestinationBridge.sol /*////////////////////////////////////////////////////////////// Public Functions //////////////////////////////////////////////////////////////*/ /** * @notice internal function to mint a transaction if it has passed the threshold * for the number of approvers * * @param txnHash The hash of the transaction we wish to mint */ function _mintIfThresholdMet(bytes32 txnHash) internal {..//}
NatSpec is a boon to all Solidity developers. Not only does it provide a structure for developers to document their code within the code itself, it encourages the practice of documenting code. When future developers read code documented with NatSpec, they are able to increase their capacity to understand, upgrade, and fix code. Without code documented with NatSpec, that capacity is hindered.
The Ondo codebase does have a high level of documentation with NatSpec. However there are numerous instances of functions missing NatSpec.
Using old versions of 3rd-party libraries in the build process can introduce vulnerabilities to the protocol code.
Review the latest version of the OpenZeppelin contracts and upgrade.
An inconsistent coding style can be found throughout the codebase. Some examples include:
Some of the parameter names in certain functions lack the underscores as seen in other cases. To enhance code readability
and adhere to the Solidity style guide standards, it is recommended to incorporate underscores in the parameter names. This practice contributes to maintaining a consistent and organized codebase.
To improve the overall consistency and readability of the codebase, consider adhering to a more consistent coding style by following a specific style guide.
In the constructor functions it is not specified in the documentation if the admin/roles will be an EOA or a contract. Consider improving the docstrings to reflect the exact intended behaviour, and using Address.isContract
function from OpenZeppelinโs library to detect if an address is effectively a contract.
Consider using named parameters in mappings (e.g. mapping(address account => uint256 balance)) to improve readability. This feature is present since Solidity 0.8.18. For example:
mapping(address account => uint256 balance);
#0 - c4-pre-sort
2023-09-08T08:31:15Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-09-21T10:25:23Z
kirk-baird marked the issue as grade-b
๐ Selected for report: catellatech
Also found by: 0xAsen, 0xE1D, 0xStalin, 0xmystery, Breeje, Bube, DedOhWale, JayShreeRAM, K42, Krace, castle_chain, hals, hunter_w3b, kaveyjoe, m4ttm, mahdikarimi, nirlin, peanuts, sandy
255.0803 USDC - $255.08
Ondo Finance
is a blockchain platform that offers investment opportunities with cryptocurrencies backed
by U.S. dollar bank deposits (USDY)
. USDY
earns interest over time, increasing its value. Ondo Finance
introduces rUSDY
, a variant of USDY
that automatically adjusts in quantity to reflect interest but maintains a nominal value of 1 dollar
per token
. Oracles
track the value of USDY
. Ondo Finance
enables asset transfers between blockchains
through bridge
contracts.
SourceBridge.solThis contract
facilitates the transfer of tokens between different blockchains using the Axelar protocol
, ensuring that tokens burned on one chain are minted on the corresponding destination chain, provided certain conditions are met, and the necessary gas is paid. Additionally, it provides administrative functionalities and a pause mechanism
when needed.
DestinationBridge.sol: This contract
functions as the destination chain bridge
for USDY
tokens. Its primary purpose is to facilitate the seamless transfer of USDY
tokens from a source blockchain to the destination blockchain where this contract resides. This bridge
contract plays a pivotal role in enabling cross-chain
interoperability and ensuring that USDY
tokens can be securely and efficiently moved between different blockchain networks
.
rUSDY.sol: This contract
serves as the backbone for an interest-bearing
token where users can wrap
and unwrap
their USDY
tokens to earn interest
, and it includes features for access control
and address management
.
rUSDYFactory.sol: is This is a factory contract
that allows the deployment
of upgradable instances
of the rUSDY token
contract. It is managed by a guardian address
, and the deployment process involves creating an implementation contract
, a proxy admin contract
, and a proxy contract
for the token
. The code is designed to facilitate the upgradeability
of the rUSDY
token and includes functions for batched external calls
.
RWADynamicOracle.sol: this contract
is a dynamic Oracle
that provides the price of USDY
based on configured time ranges
and daily interest rates
. It also includes mechanisms
for pausing
and access control
to manage the ranges and contract
operation.
IRWADynamicOracle: thi is an interface
that sets a standard for any contract wishing to provide information about the price of RWA
(Asset-Backed Real World Assets) or similar assets. Contracts
that implement this interface
must provide a getPrice()
function that returns the current price of RWA
. The interface
does not contain implementation logic but simply establishes a common structure for communication with dynamic asset price oracles
.
The SourceBridge
contract uses the onlyOwner
modifier to restrict access to important administrative functions such as configuring destination chain-to-contract, pausing / unpausing the contract, and executing batch calls to other contracts
.
onlyOwner
is also present in these functions of the contract DestinationBridge
------> addApprover, removeApprover, addChainSupport, setThresholds, setMintLimit, setMintLimitDuration, pause, unpause, and rescueTokens.
address
that deploys
the contract
and possesses the owner role
can execute these functions. The owner
has full control
over the contract and its administrative functions.In the rUSDY contract
, we found some roles
, such as:
/// @dev Role based access control roles bytes32 public constant USDY_MANAGER_ROLE = keccak256("ADMIN_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURN_ROLE"); bytes32 public constant LIST_CONFIGURER_ROLE = keccak256("LIST_CONFIGURER_ROLE");
USDY_MANAGER_ROLE: This role has access to functions related to the management
of the USDY
token, such as changing the oracle
that updates the USDY price
.
MINTER_ROLE: This role has the ability to create new rUSDY tokens
by minting them. It is responsible for the wrap
function, which allows users to convert USDY into rUSDY
.
PAUSER_ROLE: This role can pause
and unpause
the operations of the rUSDY
contract. When the contract is paused, transfers and other operations are not available.
BURNER_ROLE: This role allows administrators to burn
(delete) rUSDY
from a specific account using the burn
function.
LIST_CONFIGURER_ROLE: This role is used to configure the blocklist
, allowlist
, and sanctions list
. Administrators with this role can change
the addresses
in these lists
.
The rUSDYFactory
contract defines the following privilege roles:
bytes32 public constant DEFAULT_ADMIN_ROLE = bytes32(0);
guardian
address has access to certain functions of the contract, such as deployrUSDY
.modifier onlyGuardian() { require(msg.sender == guardian, "rUSDYFactory: You are not the Guardian"); _; }
The RWADynamicOracle
contract defines the following roles of privileges:
bytes32 public constant SETTER_ROLE = keccak256("SETTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
price range
for USDY
.pause
and unpause
the operation of the oracle
.We asked the sponsors about who will be responsible for these roles, and this was their response:
ali2251 โ 09/5/2023 at 10:22 it will be managed by multisigs controlled by the protocol
Given the level of control
that these roles
possess within the system
, users must place full trust in the fact that the entities
overseeing these roles
will always act correctly
and in the best interest
of the system
and its users
.
We have decided to create diagrams
detailing each part of the functions
of the smart contracts
provided by the Ondo Finance
protocol and to create a summary of the functionality of each of the contracts
. This approach proves to be effective
for us
as it allows us to thoroughly understand all the functionalities of each contract
and visually document
what we have comprehended
through diagrams
. Furthermore, we believe that this approach can be useful in enhancing the understanding of the contracts
among developers
, auditors
, and users
.
5 contracts
and 1 Interface
. Here's a detailed diagrams of the essential components of each ones:The architecture
of the Ondo Finance
project seems solid in general, but there is always room for improvements
and adjustments
. Here are some areas that could be improved:
Upgradeability: Since the contracts rUSDY
, rUSDYFactory
are upgradeable, having a clear and secure process for performing upgrades
is important. It may also be useful to implement time limits for upgrades
or allow a majority of users to approve upgrades
.
Governance: Consider incorporating a governance system
to allow users to vote on key decisions
, such as changes in interest rates
or adjustments
to system parameters.
Oracles and Data Consistency: The consistency and accuracy of oracle
data are crucial. You can explore the possibility of using multiple oracles
or implementing consensus mechanisms
to ensure data reliability.
Testing and Simulations
: Even though the project implements several tests
, upon reviewing the codebase
, there are several crucial functions that don't, such as rUSDY:transferFrom
. Conduct thorough testing
of all contracts and functions
and simulations
to understand how they will behave under various market conditions. This can help anticipate potential issues.
Ondo Finance
project is quite comprehensive and detailed, providing a solid overview of how Ondo
is structured and how its various aspects function. However, we have noticed that there is room for additional details, such as diagrams
, to gain a deeper understanding of how different contracts interact and the functions
they implement. With considerable enthusiasm
, we have dedicated some days to creating diagrams
for each of the contracts.
We are confident that these diagrams
will bring significant value to the protocol as they can be seamlessly integrated into the existing documentation
, enriching it and providing a more comprehensive and detailed understanding for users
, developers
and auditors
.Here's an analysis of potential systemic and centralization risks in the provided contracts:
Loss of Funds Risk: If the contract stores or manages digital assets (such as tokens), there is an inherent risk of funds being lost due to errors in the contract's logic or malicious attacks.
The protocol uses a proxy
, and according to the Documentation
, the type of proxy
is:
* 3) TransparentUpgradeableProxy - OZ, proxy contract. Admin is set to `address(proxyAdmin)`. * `_logic' is set to `address(rUSDY)`.
If the logic controlling the proxy
is not implemented correctly, there could be vulnerabilities
that allow an attacker to modify the underlying contract or the proxy
itself in an unintended way.
Price Manipulation Risk: Since these contracts are designed to calculate the price of USDY
based on interest rates
and price ranges
, there is a risk that parameters
may be manipulated
or that input data
may be compromised, potentially leading to incorrect prices
.
Centralized Administration Risk: If the contract has administrator roles
that can modify settings
or pause the contract
, there is a risk that these capabilities may be used improperly or become targets for attacks.
Third-Party Dependency Risk: Contracts rely on external data sources, such as @openzeppelin/contracts, and there is a risk that if any issues
are found with these dependencies
in your contracts, the Ondo finance
protocol could also be affected
.
old versions
of OpenZeppelin
are used in the project, and these should be updated to the latest version
:29: "@openzeppelin/contracts": "^4.8.3", 30: "@openzeppelin/hardhat-upgrades": "1.22.1",
The latest version
is 4.9.3
(as of July 28, 2023), while the project uses version 4.8.3
.
That's why we strongly recommend
that once the issues
in the codebase
identified by C4 Wardens
are known
, the Ondo Finance team
takes action to implement the mitigations
and make their protocol a robust
financial ecosystem for all participants
.
While audits
help in identifying
code-level issues
in the current implementation and potentially the code deployed
in production, the Ondo Finance
team is encouraged to consider incorporating monitoring activities in the production environment. Ongoing monitoring of deployed contracts helps identify potential threats and issues affecting production environments. With the goal of providing a complete security assessment
, the monitoring recommendations
section raises several actions addressing trust assumptions and out-of-scope components that can benefit from on-chain monitoring
.
unexpectedly
large withdrawal, may indicate unusual behavior
of the contracts or an ongoing attack.These may indicate a user interface
bug, an ongoing attack or other unexpected
edge cases.
A total of 3 days
were dedicated to completing this audit, distributed as follows:
Ondo Finance
.analysis
, incorporating meticulously crafted diagrams
derived from the contracts
and information
provided by the protocol.15 hours
#0 - c4-pre-sort
2023-09-08T14:46:39Z
raymondfam marked the issue as high quality report
#1 - tom2o17
2023-09-13T15:29:31Z
This one is the best.
#2 - c4-sponsor
2023-09-13T15:29:35Z
tom2o17 (sponsor) acknowledged
#3 - c4-judge
2023-09-24T07:03:54Z
kirk-baird marked the issue as grade-a
#4 - c4-judge
2023-09-24T07:03:58Z
kirk-baird marked the issue as selected for report