Platform: Code4rena
Start Date: 23/02/2024
Pot Size: $92,000 USDC
Total HM: 0
Participants: 47
Period: 10 days
Judge: 0xTheC0der
Id: 336
League: ETH
Rank: 46/47
Findings: 1
Award: $22.02
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: roguereggiant
Also found by: 0xepley, Aamir, Al-Qa-qa, LinKenji, MSK, McToady, Myd, SAQ, Sathish9098, ZanyBonzy, aariiif, cudo, emerald7017, fouzantanveer, hassanshakeel13, hunter_w3b, ihtishamsudo, kaveyjoe, peanuts
22.023 USDC - $22.02
Technical overview of the protocol, focusing on its design, functionalities, and key components.
Staking Tokens
: Users stake an ERC20 governance token (referred to as STAKE_TOKEN) to participate in the protocol. This token is assumed to be delegable, meaning it carries voting power that can be assigned to different addresses.
Reward Tokens
: Rewards are distributed in a separate ERC20 token (REWARD_TOKEN). The distribution rate and duration are controlled by the protocol based on the rewards received from external sources.
Deposits
: Each staking action creates a Deposit record, which tracks the staked amount, the owner of the stake, the delegatee (the address receiving the voting power), and the beneficiary (the address earning the rewards).
Delegation and Voting Power
: Stakers can delegate their voting power to a chosen address. This allows users to participate in governance without removing their assets from earning potential.
Reward Distribution
: Rewards are streamed over time, based on the duration set by the protocol (defaulting to 30 days in the provided example). Each staker's reward is proportional to their share of the total staked amount.
Staking
: Users can stake their tokens to start earning rewards. They can choose a delegatee for governance participation and a beneficiary for reward collection, which can be themselves or different addresses.
Withdrawing
: Stakers can withdraw their tokens at any time, which stops further reward accumulation.
Delegation Management
: Users can change the delegatee for their stake, allowing them to shift their governance representation without affecting their staking position.
Reward Management
: Beneficiaries can claim their accumulated rewards at any time. The protocol supports updating reward rates and durations upon receiving new rewards.
Admin Controls
: An admin address has special permissions, including enabling or disabling reward notifier addresses, which are critical for managing reward inflows.
Nonces for Signature Validation
: Used to prevent replay attacks in delegated staking and withdrawal functions.
SafeERC20
: Utilized for secure token transfers, mitigating risks associated with tokens that don't return a boolean value.
Custom Errors
: Provide detailed reasons for transaction failures, improving debuggability and user experience.
Modular Design
: Separation of concerns among different contract functionalities for easier maintenance and upgradeability.
In the UniStaker, rewards appear to be calculated based on changes in state (such as staking, withdrawing, or receiving new rewards) rather than on a time-weighted basis. There is no explicit time-lock mechanism or detailed time-weighted reward calculation present in the snippets you provided.
If the system updates reward rates or distributions based on receiving new rewards (notifyRewardAmount) or user actions (staking, withdrawing), but does not account for the duration each stake was active during the reward period, it could be manipulated. For instance, if rewardPerTokenAccumulated() and the related distribution logic do not account for the exact time each user's funds were staked but only the amount, users could exploit this.
In the code, there is a function to stake tokens (stake, stakeMore), but without seeing a mechanism that tracks the exact staking duration in relation to the reward calculation, users could potentially deposit large amounts just before a known reward calculation event or snapshot.
Users like Alice could observe when rewards are likely to be calculated or distributed (if there's a predictable pattern or timing). She could then stake a large amount right before this time and withdraw soon after, exploiting the lack of duration-based checks.
A different angle could be that users, encouraged by potential rewards in the UniStaker system, independently choose to delegate their tokens to liquidity pools. While not a direct function of the provided code, if rewards or system incentives indirectly promote this behavior, the concept of "delegation" could loosely apply here. However, this action would be outside the direct scope of the UniStaker smart contract's functionalities as provided.
Imagine a scenario where UniStaker integrates with a Uniswap V3 pool. If part of the staking contract allowed for sending tokens to participate in a liquidity pool, the tokens would be subject to the price dynamics of the assets in the pool, leading to potential impermanent loss.
The UniStaker contract includes functionality for users to stake governance tokens and delegate their associated voting power. This is evident from the presence of delegate functions and the integration with IERC20Delegates, which is a hypothetical interface suggesting these tokens have delegatable voting rights.
When a user stakes tokens in UniStaker, they can designate a delegatee – another address that will receive the voting power associated with the staked tokens. This mechanism is intended to allow users to continue participating in governance decisions indirectly while their tokens are locked in the staking contract.
In a scenario where a significant number of tokens are staked, a large stakeholder or a coordinated group could delegate voting power to a single address, effectively centralizing governance power. If these stakeholders have malicious intent or diverging interests from the wider community, they could use this concentrated voting power to influence decisions in their favor, such as proposing and approving changes that could compromise the protocol's security, fairness, or transparency.
Even without a single large stakeholder, smaller holders could coordinate their actions to pool their delegated voting power, overcoming the decentralization intended by the token distribution. This pooled power could then be used to push through proposals beneficial to the group but detrimental to the broader user base or the long-term health of the protocol.
High Gas Fees, Low Rewards
: Suppose the Ethereum network is experiencing high congestion, leading to elevated gas fees. If the UniStaker reward rates are static or fail to account for these increased costs, users conducting staking or reward claiming transactions might end up paying more in gas than they earn in rewards.
Inadequate Reward Adjustment
: If market conditions change – say, the value of the staked token increases significantly – but the UniStaker protocol continues to distribute rewards based on outdated valuations, the real value of the rewards might become less enticing compared to simply holding the token or engaging in other investment activities.
The system’s security could be compromised if delegated addresses (delegatees) have too much control or are not properly secured.
Users might exploit the reward calculation mechanism, as discussed earlier, by depositing large amounts right before a snapshot and withdrawing right after, thereby maximizing rewards without genuinely contributing to the protocol.
If the protocol becomes unpopular or if users rapidly withdraw their stakes, the system could face liquidity issues, impacting its ability to function effectively.
Significant fluctuations in the value of the staked tokens or rewards can affect participation incentives and the overall stability of the protocol.
If UniStaker interacts with external contracts or platforms (for rewards or additional functionalities), vulnerabilities or changes in those external systems could adversely affect UniStaker.
If the system relies on external oracles for price feeds or other external data, manipulation or inaccuracies in these feeds could lead to incorrect calculations or decisions within the protocol.
Changes in regulatory landscapes or the discovery of non-compliance with current regulations could disrupt operations or lead to protocol shutdown.
Multi-Transaction Atomicity
: While Multicall allows for batched transactions, inconsistencies or failures in one part of a batched call could have unforeseen impacts, especially if atomicity (complete success or failure of all included transactions) is assumed by users or the protocol.
SafeERC20 Assumptions
: The SafeERC20 utility is designed to mitigate issues with tokens that do not return a boolean value. However, relying on external libraries still subjects the protocol to risks associated with these libraries' updates, vulnerabilities, or incompatibilities with certain token contracts.
External Reward Feeds and Manipulation
: If the reward notification system relies on external inputs (e.g., off-chain computations or third-party contract calls), there's a risk associated with the accuracy and security of these inputs. Manipulation or errors could lead to incorrect reward distributions.
Admin Control and Upgradeability
: If the UniStaker has admin-controlled functions or upgradeability features, there's a risk related to the centralization of control and potential for malicious or erroneous upgrades affecting the system.
In the code, there are several instances where an admin role is referenced. Functions like setAdmin
, setRewardNotifier
, and any similar functions that may have been included, grant significant control to the admin.
Changing Administrative Control
: The setAdmin function allows the current admin to transfer administrative rights to a new address. If misused, an admin could transfer control to a malicious party, or to multiple colluding accounts, compromising the protocol’s integrity.
Modifying Reward Notifiers
: The ability to enable or disable reward notifier addresses (setRewardNotifier) can be abused to divert or freeze reward distribution, potentially redirecting rewards to addresses controlled by the admin or simply halting rewards to legitimate stakers.
Arbitrary Updates and Actions
: If there are functions within the contract that allow the admin to update staking requirements, reward rates, or withdrawal terms, an admin could alter these to their advantage or to the detriment of users.
Misuse of Emergency Powers
: Admins have the ability to pause staking, withdrawals, or rewards claiming, which can be necessary for security but also susceptible to abuse, disrupting normal protocol operations for personal gain or malicious intent.
The UniStaker protocol, based on the details provided, is designed to facilitate staking, reward distribution, and delegation of voting power within a decentralized finance (DeFi) ecosystem. The core business logic of the UniStaker protocol revolves around incentivizing users to stake tokens, thereby securing liquidity and potentially participating in governance, while earning rewards. It balances user participation with system security and governance through a series of smart contracts that manage staking, delegation, and rewards. This creates an ecosystem where users are rewarded for contributing to the protocol's success and stability, aligning individual incentives with the broader goals of the UniStaker protocol and associated DeFi platforms.
Efficient Data Storage
: Minimize storage operations and optimize data structures. Use memory for temporary variables and consider packing multiple Boolean values into single storage slots.
Loop Optimization
: Avoid loops that could grow unbounded over time, leading to increased gas costs. Optimize loops and consider off-chain computations when feasible.
Minimize Contract Calls
: Reduce external contract calls when possible, as they are costly in terms of gas. Batch processes or updates if applicable.
Proxy Patterns
: If the contract needs to be upgradable, consider using proxy patterns like the Transparent Proxy Pattern or the Universal Upgradeable Proxy Standard (UUPS). Ensure that upgradeability is secure and transparent.
Parameterization
: Allow for certain parameters (e.g., reward rates, lock-up periods) to be adjusted through governance mechanisms, enabling the protocol to adapt to changing conditions.
Community Involvement
: Engage with the user community for feedback, suggestions, and beta testing. Community involvement can provide valuable insights and help identify issues.
Security Patterns and Checks
: Use established security patterns, such as checks-effects-interactions, to mitigate common vulnerabilities like reentrancy. Utilize modifiers for common precondition checks.
Naming Conventions
: Use clear, descriptive names for functions, variables, and contracts to improve readability and facilitate understanding of the code's purpose.
In conclusion, the UniStaker protocol and related contracts like V3FactoryOwner represent sophisticated implementations within the DeFi ecosystem, aimed at facilitating staking, governance, and rewards distribution. These protocols leverage the inherent transparency, security, and efficiency of blockchain technology to offer users opportunities for participation and investment.
5 hours
#0 - c4-judge
2024-03-14T18:06:50Z
MarioPoneder marked the issue as grade-b