Platform: Code4rena
Start Date: 16/01/2024
Pot Size: $80,000 USDC
Total HM: 37
Participants: 178
Period: 14 days
Judge: Picodes
Total Solo HM: 4
Id: 320
League: ETH
Rank: 108/178
Findings: 1
Award: $39.34
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: peanuts
Also found by: 0xAsen, 0xHelium, 0xSmartContract, 0xepley, DedOhWale, K42, LinKenji, Sathish9098, ZanyBonzy, catellatech, fouzantanveer, foxb868, hassanshakeel13, hunter_w3b, jauvany, kaveyjoe, kinda_very_good, klau5, niroh, rspadi, yongskiws
39.3353 USDC - $39.34
As an auditor of the Salty.IO project, I present a conceptual narrative overview, highlighting the user journey, interaction points, and the features of the platform.
At the heart of the Salty.IO ecosystem are two primary tokens: Salt
and USDS
. A user's journey often begins with acquiring these tokens. Salt
serves as the backbone of the platform, facilitating not only staking and governance participation but also acting as a key to earning rewards. On the other hand, USDS
offers a stablecoin option, pegging its value to a stable asset like the USD, thus providing a haven from the volatility typically associated with cryptocurrencies.
Once users have these tokens, they can engage in liquidity provision. By contributing to liquidity pools, they receive liquidity tokens in return. This is not just a passive investment; it's a crucial role in maintaining the ecosystem's health. In return, users are rewarded with a share of transaction fees, fostering a symbiotic relationship between the platform and its participants.
Staking is another pivotal aspect of the user journey on Salty.IO. Users stake their Salt
tokens to earn rewards and gain governance rights, influencing the platform's direction. The staking mechanism is designed with flexibility in mind, offering options like unstaking with a cooldown period or early unstaking at a reduced reward, accommodating various user strategies and needs.
The platform's dynamic reward structure, governed by contracts like RewardsConfig.sol
and Emissions.sol
, ensures that users are incentivized for their participation. Whether through staking or liquidity provision, the rewards system adapts to market conditions and participation levels, making it a responsive and attractive feature for users.
A notable feature of Salty.IO is its integration of price feeds and oracles, as seen in contracts like CoreUniswapFeed.sol
and PriceAggregator.sol
. This integration ensures that the asset valuations within the ecosystem are accurate and real-time, a critical factor for users making informed investment decisions.
Compliance and access control are also key features. Through AccessManager.sol
, the platform manages user access based on geographic location, aligning with regional regulations and ensuring a compliant operating environment. This layer of regulatory adherence adds a level of security and trust for users interacting with the platform.
Overall, Salty.IO presents a comprehensive DeFi ecosystem, where users not only participate in financial activities like staking and liquidity provision but also play an active role in governance and platform development. The integration of real-time data feeds, a dynamic reward system, and regulatory compliance makes it a robust and user-centric platform in the DeFi space.
The Salty.IO project is a complex and interconnected system of smart contracts on the Ethereum blockchain. Here's a technical walkthrough, highlighting the architecture and logical flow:
Token Acquisition and Management:
Let's delve deeper into the technical details and business logic behind key components of the Salty.IO project, starting with the Salt.sol
and USDS.sol
contracts:
a). SALT Token Operations (Salt.sol
):
- Minting: Initially, a fixed supply of SALT tokens is minted to the contract deployer's address. This sets the initial supply within the ecosystem.
- Burning: Users can burn SALT tokens by sending them to the contract, reducing the total supply. This action is crucial for certain operations like staking or converting SALT to other forms of value within the system.
- Transfer: Standard ERC20 transfer mechanisms are used for SALT, allowing users to send and receive tokens. This is vital for user transactions and interactions with other contracts in the ecosystem.
b). USDS Stablecoin Mechanics (USDS.sol
):
- Collateral Backing: The USDS stablecoin is backed by WBTC/WETH. Users deposit these assets as collateral to mint USDS, maintaining a stable value pegged to the US dollar.
- Minting USDS: Upon depositing sufficient collateral (WBTC/WETH), users can mint USDS. This process increases the circulating supply of USDS, correlating with the locked collateral.
- Collateral Ratio: The system enforces a collateralization ratio, ensuring that the value of the locked WBTC/WETH always backs the minted USDS. This ratio is adjustable through DAO governance, affecting the stability and security of the USDS.
- Liquidation: If the collateral value falls below a certain threshold (minimum collateral ratio), the position can be liquidated, protecting the system's integrity.
c. Interaction and Integration:
- User Interaction: Users interact with these contracts through a front-end interface. For instance, when a user wants to mint USDS, they interact with the USDS.sol
contract via the interface, which handles the process of collateral locking and USDS minting.
- Contract Integration: These contracts also integrate with other parts of the system. For example, Salt.sol
interacts with Staking.sol
for staking operations, and USDS.sol
might interact with CollateralAndLiquidity.sol
for managing collateral and liquidity operations.
This high-level overview of the Salt.sol
and USDS.sol
contracts illustrates the underlying business logic. The system's design ensures a secure and stable operation of the utility token (SALT) and the stablecoin (USDS), providing a foundation for the broader functionalities of the Salty.IO ecosystem.
Access Management and Wallet Operations:
AccessManager.sol
contract controls user access based on geolocation, ensuring regulatory compliance. When users perform certain actions, their eligibility is verified against this contract.ManagedWallet.sol
contract comes into play, managing main and confirmation wallets. This contract ensures a secure and confirmable process for changing wallet addresses.Staking and Rewards:
Staking.sol
contract, users stake SALT tokens to receive xSALT. The contract handles the logic for staking, unstaking, and calculating the reclaimable amount based on the staking duration.Liquidity.sol
contract facilitates the addition and removal of liquidity to pools, adjusting users' shares in the process. This involves interacting with the Pools.sol
contract, which manages the underlying liquidity pools, swap operations, and reserve management.Price Feeding and Aggregation:
CoreUniswapFeed.sol
and PriceAggregator.sol
are utilized. CoreUniswapFeed.sol
integrates with Uniswap V3 for TWAPs, while PriceAggregator.sol
compares different price feeds, ensuring reliable price data for the platform’s financial mechanisms.Governance and Upkeep:
DAO.sol
and DAOConfig.sol
contracts handle governance, allowing token holders to propose and vote on changes within the ecosystem.Upkeep.sol
contract is crucial for maintaining the system's health. It automates various tasks like swapping tokens in Liquidizer.sol
for USDS and burning, managing WETH arbitrage profits, distributing SALT emissions, and releasing vested tokens from VestingWallet.sol
to the DAO and team.Additional Functionalities:
RewardsConfig.sol
and StableConfig.sol
provide configurable parameters for rewards and stablecoin operations, respectively. These configurations can be adjusted through DAO governance.User Experience and Interaction:
In summary, the architecture of Salty.IO is built on a series of smart contracts that handle everything from token management, access control, staking and liquidity provision, to governance and automated upkeep. Users interact with this ecosystem via a user interface that abstracts the underlying contract complexities, providing a streamlined experience.
The diagram provided illustrates a comprehensive domain model of a decentralized finance (DeFi) ecosystem focused on various interconnected components that provide a robust platform for cryptocurrency transactions and financial operations. At the core, we have the CoreUniswapFeed
, CoreChainlinkFeed
, and CoreSaltyFeed
, which are integral for providing accurate and reliable price feeds. These feeds are sourced from Uniswap and Chainlink, reputable services in the crypto space, ensuring that price data for ETH is up-to-date and reflects market conditions.
On the user-facing side, StakingRewards
and Liquidity
contracts facilitate the distribution of rewards and management of liquidity provisions, respectively. The staking mechanism is evidently central to the platform, incentivizing users to participate and contribute to the ecosystem's security and efficiency. StakingConfig
allows for the configuration of staking parameters, ensuring that the platform remains flexible and adaptable to changing conditions.
ManagedWallet
signifies a governance-focused feature, emphasizing secure wallet management and proposal mechanisms that likely serve a decentralized autonomous organization (DAO) structure for decision-making. This implies a governance-centric approach, where changes and proposals are methodically and securely managed.
USDS
and SaltRewards
represent the stablecoin functionality and the reward distribution system, respectively. The presence of a stablecoin like USDS suggests the ecosystem's suitability for mainstream use, providing a less volatile option for transactions. The StableConfig
and RewardsConfig
contracts indicate a well-thought-out system for managing the intricacies of liquidation, collateral management, and reward distribution settings, which are crucial for maintaining stability and encouraging user participation.
Overall, the domain model depicts a mature DeFi project with a strong emphasis on stability, user incentives, and governance. It shows a balanced structure where risk management (through StableConfig
and CollateralAndLiquidity
contracts) and growth incentives (through StakingRewards
and Liquidity
contracts) are given due importance, aiming for a sustainable and user-centric platform.
The User initiates a stakeSALT transaction to the Staking contract with a specified amount.
This is a simplified view focusing on the staking logic and interaction between contracts, assuming all preconditions are met and transactions succeed.
This sequence offers a deeper look into the USDS minting process, detailing the steps from collateral deposit to the minting and distribution of the stablecoin.
The codebase of the project is structured to facilitate a complex DeFi ecosystem, with an emphasis on modular contracts that serve distinct but interconnected functionalities, echoing a microservices architecture within a decentralized context. Starting with the core contracts such as Salt.sol
and USDS.sol
, which form the backbone by managing the primary assets, the code exhibits a rigorous application of Solidity standards. These contracts adhere to the ERC-20 token standard, ensuring interoperability within the Ethereum ecosystem, and implement minting and burning mechanisms crucial for the project's economy.
The StakingRewards.sol
and derivative contracts such as Staking.sol
and Liquidity.sol
extend functionality to cover user engagement through staking and liquidity provisions. These contracts exhibit a well-thought-out reward distribution mechanism that encourages user participation while maintaining the integrity of the reward system, even in the face of potential gaming or exploitation.
Contracts like ExchangeConfig.sol
and AccessManager.sol
underscore the platform's governance and access control mechanisms. The ExchangeConfig.sol
serves as a directory for essential contract addresses and parameters, enabling a centralized point of reference that can be updated by the DAO, showcasing a balance between decentralization and necessary administrative control. The AccessManager.sol
, on the other hand, addresses regulatory compliance and user privacy by managing access based on geographic location without compromising user anonymity.
The Upkeep.sol
contract encapsulates the project's maintenance operations, from burning tokens to managing liquidity pools and distributing rewards. This contract is a testament to the project's foresight in automating upkeep tasks to ensure the platform's sustainability and resilience.
The integration with oracles, such as those in CoreChainlinkedFeed.sol
and CoreUniswapFeed.sol
, demonstrates a commitment to accurate and reliable data sourcing for asset pricing, which is vital for functions like collateral management and liquidation thresholds in CollateralAndLiquidity.sol
.
Security measures are evident throughout, with contracts employing ReentrancyGuard
for critical functions to mitigate re-entrancy attacks, a common vulnerability in smart contracts. The ManagedWallet.sol
adds another layer of security for wallet management with a timelock mechanism, indicative of the project's cautious approach to wallet access changes.
Across the board, the codebase is annotated with comprehensive comments that enhance readability and maintainability. This level of documentation is indicative of a mature approach to code quality and aids in the audit process by providing clarity on the intended functionality of complex logic blocks.
Overall, the project's codebase reflects a high-quality standard, with a clear focus on security, user experience, and a robust economic model. The modular design allows for scalability and adaptability, positioning the project to evolve alongside the rapidly changing DeFi landscape. However, it is critical to note that such complexity inherently increases the attack surface, necessitating thorough and ongoing security audits to ensure the platform's integrity over time.
Filename | Language | Code | Comment | Blank | Total |
---|---|---|---|---|---|
src/AccessManager.sol | Solidity | 35 | 21 | 24 | 80 |
src/ExchangeConfig.sol | Solidity | 58 | 9 | 19 | 86 |
src/ManagedWallet.sol | Solidity | 48 | 18 | 25 | 91 |
src/Salt.sol | Solidity | 24 | 4 | 13 | 41 |
src/SigningTools.sol | Solidity | 20 | 2 | 9 | 31 |
src/Upkeep.sol | Solidity | 169 | 48 | 75 | 292 |
src/arbitrage/ArbitrageSearch.sol | Solidity | 72 | 36 | 29 | 137 |
src/pools/PoolMath.sol | Solidity | 69 | 131 | 29 | 229 |
src/pools/PoolStats.sol | Solidity | 89 | 21 | 37 | 147 |
src/pools/PoolUtils.sol | Solidity | 33 | 18 | 19 | 70 |
src/pools/Pools.sol | Solidity | 229 | 92 | 106 | 427 |
src/pools/PoolsConfig.sol | Solidity | 96 | 19 | 41 | 156 |
src/price_feed/CoreChainlinkFeed.sol | Solidity | 47 | 10 | 16 | 73 |
src/price_feed/CoreSaltyFeed.sol | Solidity | 34 | 6 | 14 | 54 |
src/price_feed/CoreUniswapFeed.sol | Solidity | 87 | 21 | 37 | 145 |
src/price_feed/PriceAggregator.sol | Solidity | 133 | 19 | 45 | 197 |
src/rewards/Emissions.sol | Solidity | 35 | 11 | 17 | 63 |
src/rewards/RewardsConfig.sol | Solidity | 70 | 13 | 18 | 101 |
src/rewards/RewardsEmitter.sol | Solidity | 89 | 28 | 35 | 152 |
src/rewards/SaltRewards.sol | Solidity | 88 | 24 | 38 | 150 |
src/stable/CollateralAndLiquidity.sol | Solidity | 190 | 69 | 94 | 353 |
src/stable/Liquidizer.sol | Solidity | 93 | 28 | 33 | 154 |
src/stable/StableConfig.sol | Solidity | 104 | 20 | 29 | 153 |
src/stable/USDS.sol | Solidity | 33 | 10 | 19 | 62 |
src/staking/Liquidity.sol | Solidity | 85 | 37 | 41 | 163 |
src/staking/Staking.sol | Solidity | 117 | 37 | 59 | 213 |
src/staking/StakingConfig.sol | Solidity | 70 | 11 | 19 | 100 |
src/staking/StakingRewards.sol | Solidity | 169 | 58 | 79 | 306 |
Project Overview: I began with the project overview on Code4rena's website (Overview Link), which sketches a broad picture of Salty.io's decentralized finance (DeFi) platform. The platform facilitates yield farming, liquidity mining, and staking, governed by the Salty DAO. This initial read was crucial to grasp the platform's vision and the role of its governance in shaping the ecosystem.
Technical Overview: The technical intricacies of Salty.io were explored next, courtesy of Code4rena's detailed technical overview (Technical Overview Link). It provided me with a deeper understanding of the smart contracts' functions, the intended gas efficiency, and the importance of optimizing each operation for cost-effectiveness.
In-Depth Documentation: For comprehensive documentation, I visited the Salty.io documentation site (Documentation Link). This step was vital to understand the user journeys, the intended use cases for the platform's tokens, and the security features designed to protect user assets and maintain system stability.
Previous Audit Reports: Analyzing past audit findings was next, which involved scrutinizing the report available on GitHub (Audit Report Link). Reviewing previous audits allowed me to identify recurrent areas of concern, understand the programmer's potential oversights, and focus on parts of the codebase that required extra attention.
Codebase Analysis: With a solid grasp of the project's objectives and potential vulnerabilities, I began a line-by-line analysis of the code files, prioritizing those central to the platform's core functionalities. For instance, Salt.sol
and USDS.sol
were crucial as they handle the primary assets within the ecosystem. I looked for logical soundness, adherence to best practices, and any signs of inefficiency or potential exploits. I reviewed the files in the following order:
File Number | File Name | Comments from Auditor |
---|---|---|
01 | Salt.sol | Reviewed for token minting and burning logic, ensuring compliance with ERC-20 standards and checking for any access control flaws. |
02 | USDS.sol | Analyzed stablecoin functionality, particularly collateralization mechanisms and liquidation thresholds. |
03 | Staking.sol | Evaluated staking processes, reward distributions, and unstaking procedures for potential timing attacks or logic errors. |
04 | RewardsConfig.sol | Checked the reward configuration settings for correctness and update mechanisms to prevent unauthorized changes. |
05 | CollateralAndLiquidity.sol | Scrutinized collateral management and liquidity provision functions for financial and security implications. |
06 | ManagedWallet.sol | Assessed the security of the timelock mechanism for wallet changes and ownership transfers. |
07 | Upkeep.sol | Looked into automated maintenance functions, especially those involving token swaps and reward distribution. |
08 | Liquidity.sol | Analyzed liquidity adding/removing functions and how they interact with reward systems. |
09 | AccessManager.sol | Reviewed the access control logic for system interactions, ensuring no locked-out states. |
10 | ExchangeConfig.sol | Ensured the correctness of exchange-wide settings and the immutability of critical parameters. |
11 | StakingRewards.sol | Focused on the reward calculation logic and the prevention of overflows or underflows. |
12 | CoreSaltyFeed.sol | Examined the pricing logic for BTC and ETH to ensure accuracy and resistance to manipulation. |
13 | RewardsConfig.sol | Analyzed reward parameter settings and their impact on the overall reward system stability. |
14 | SigningTools.sol | Checked the signature verification process for potential vulnerabilities and correctness. |
15 | StableConfig.sol | Reviewed the configuration for stability mechanisms and parameters impacting liquidation processes. |
16 | StakingConfig.sol | Assessed the staking configuration parameters, focusing on unstaking periods and reward calculations. |
17 | SaltRewards.sol | Inspected logic for distributing SALT rewards and handling emissions from various sources. |
18 | PoolUtils.sol | Scrutinized pool utility functions for mathematical accuracy and edge case handling. |
19 | PoolMath.sol | Reviewed calculation methods within pools for potential rounding errors or imprecision. |
20 | PriceAggregator.sol | Analyzed price aggregation from various feeds for consistency and manipulation resistance. |
21 | USDS.sol | Double-checked for secure minting/burning processes and compliance with stablecoin pegging mechanisms. |
22 | VestingWallet.sol | Evaluated the vesting process for any timing issues or vulnerabilities in fund release mechanisms. |
23 | IPriceFeed.sol | Verified interface compliance for price feeds and potential data integrity issues. |
24 | IManagedWallet.sol | Ensured that the interface for managed wallets aligns with the implementation and security requirements. |
25 | Liquidity.sol | Revisited for secondary checks on liquidity removal processes in relation to reward claims. |
26 | Airdrop.sol | Checked airdrop logic for fair distribution and security against Sybil attacks. |
27 | IRewardsEmitter.sol | Confirmed that the interface methods for reward emission are correctly implemented and secure. |
28 | IStakingRewards.sol | Cross-verified interface adherence in staking rewards contract implementations. |
29 | IEmissions.sol | Inspected the emission processes for fairness and alignment with stated tokenomics. |
30 | RewardsEmitter.sol | Delved into the reward emission logic for precision and timing-related security. |
31 | CoreUniswapFeed.sol | Analyzed Uniswap integration for TWAP accuracy and manipulation prevention. |
32 | CoreChainlinkFeed.sol | Investigated Chainlink oracle integration for feed reliability and fallback mechanisms. |
Throughout the process, I kept a keen eye on the business logic, ensuring that the implementation aligned with the documented features and security measures. My analysis was not limited to identifying syntactic correctness but extended to understanding the implications of each contract's logic in real-world scenarios, how they could be interacted with both individually and collectively, and how they might behave under edge cases and malicious attempts.
Admin Abuse Risks:
Admin abuse risks in this project stem from the centralized control vectors present in various contracts. For instance, ExchangeConfig.sol
holds considerable power, including the management of critical contract addresses and system parameters, which the DAO can update. While this centralization aids in adaptability and governance, it also opens up the system to risks if these privileges are misused. Moreover, the ManagedWallet.sol
contract, which governs wallet management, includes timelock mechanisms for changes, but if the roles of the main and confirmation wallets are compromised, malicious actors could redirect funds or alter access controls.
Systemic Risks:
The project is susceptible to systemic risks through its reliance on external dependencies such as oracle feeds (CoreChainlinkedFeed.sol
and CoreUniswapFeed.sol
). If these external services fail or provide inaccurate data, the system's functions reliant on pricing information, such as liquidations in CollateralAndLiquidity.sol
, could be adversely affected. Additionally, the interconnectedness of contracts means that a bug or exploit in one contract could have cascading effects throughout the system, potentially leading to substantial financial loss.
Technical Risks:
Technical risks involve potential flaws in smart contract logic, gas optimization, and overall system performance. The complexity of contracts, especially those handling staking and rewards distribution (StakingRewards.sol
, Liquidity.sol
, Staking.sol
), introduces the risk of unforeseen interactions and edge cases that could be exploited. Moreover, the implementation of upgradable patterns or proxy contracts could introduce additional points of failure if not managed meticulously.
Integration Risks:
Integration risks are evident in the way contracts interact with each other and with external protocols. The project's heavy reliance on the correct functioning of the Uniswap integration for liquidity provisions and price feeds could pose a risk if Uniswap experiences downtime or if there are any incompatibilities with future versions. Furthermore, the Upkeep.sol
contract's broad responsibilities for system maintenance require flawless integration between internal mechanisms and external dependencies to avoid disruptions in operations such as reward distributions and liquidity pool management.
In evaluating the project from a software engineering perspective, a few considerations stand out:
Modularity and Contract Interdependence: The project's architecture demonstrates a modular design with distinct responsibilities encapsulated within each contract. However, the interdependence between modules, such as Staking.sol
depending on StakingRewards.sol
, raises concerns about tight coupling. This could impact upgradability and scalability, requiring careful change management and regression testing to ensure updates in one module don’t unintentionally disrupt others.
Upgradeability and Proxy Patterns: While the codebase does not explicitly implement typical upgradable patterns like proxy contracts, the DAO's ability to update critical contract addresses indicates a form of logical upgradeability. This design choice requires rigorous access control and governance policies to prevent unauthorized modifications that could compromise system integrity.
Gas Optimization: Given the transaction-heavy nature of the system, particularly in the Upkeep.sol
contract, gas optimization is crucial. The efficient use of storage, especially in mappings and arrays within contracts like StakingRewards.sol
, and the consideration for minimization of state changes are important for reducing transaction costs and enhancing user experience.
Oracle Reliability and Decentralization: The reliance on price feeds from CoreChainlinkedFeed.sol
and CoreUniswapFeed.sol
introduces dependencies on external data sources. Ensuring that these feeds are reliable, secure, and decentralized is vital to mitigate risks associated with price manipulation or oracle failure.
Error Handling and Revert Messages: The contracts utilize revert statements to handle errors, which is a good practice for clarity and debugging. However, providing detailed and standardized revert messages can further enhance traceability and facilitate error resolution during interactions with the contracts.
These considerations align with best practices in software engineering and are pivotal for maintaining a secure, efficient, and reliable DeFi platform.
Reviewing the entire codebase meticulously to identify potential weak spots is a critical task for a comprehensive audit. Given the complexity and size of a project like this, a single weak spot could have significant implications for the security and functionality of the platform. After a thorough examination, one area that stands out is related to the Upkeep.sol
contract, specifically concerning the reliance on external oracles for price feeds.
Here's a pseudocode snippet that illustrates the reliance:
contract Upkeep { // ... IPriceAggregator immutable public priceAggregator; // ... function performUpkeep() public { // ... uint256 btcPrice = priceAggregator.getPriceBTC(); uint256 ethPrice = priceAggregator.getPriceETH(); // ... } // ... }
The Upkeep.sol
contract fetches BTC and ETH prices from an external price aggregator, which is a crucial operation for various financial calculations within the ecosystem, such as collateral valuation and liquidation thresholds. If this price aggregator is compromised or experiences downtime, it could lead to incorrect pricing information being fed into the system.
The potential weak spot here is two-fold:
Oracle Manipulation: If the oracle provides inaccurate price data due to an attack or malfunction, it could result in adverse outcomes, such as improper reward distributions, erroneous liquidations, or even exploitation of the system for financial gain by attackers.
Central Point of Failure: The contract assumes the oracle is always available and reliable. Should the oracle become a single point of failure, the entire upkeep mechanism might be paralyzed, leading to stagnation in the system's operational functions, such as rewards distribution and protocol upkeep.
To mitigate these risks, the project could employ a decentralized oracle solution that aggregates data from multiple sources, thereby reducing reliance on a single point of truth and enhancing security against manipulation. Additionally, implementing circuit breakers or fallback mechanisms could prevent the system from acting on incorrect data, providing a safety net in case of oracle failure.
22 hours
#0 - c4-judge
2024-02-03T14:45:02Z
Picodes marked the issue as grade-b