Here are some potential vulnerabilities and concerns I identified in the provided SequencerVault smart contract:
Issue: The initialize function is public and could be front-run if deployed incorrectly. If the contract deployer fails to call the initializer quickly, an attacker could initialize the contract first, gaining control.
Recommendation:
Use initializer modifier carefully.
Confirm that _disableInitializers() in the constructor is properly preventing re-initialization during deployment.
Consider restricting who can call the initialize function, perhaps using an access control mechanism or constructor arguments in a controlled environment.
Issue: No zero address validation for _token, _vaultController, _lockingPool, or _signer. This could lead to unexpected behavior if invalid addresses are passed.
Recommendation:
Add zero address checks to ensure these addresses are valid:
Issue: Although you are using SafeCastUpgradeable to cast values, there are arithmetic operations on uint128 (e.g., trackedTotalDeposits += ...) without overflow checks.
Impact: An overflow could result in wrong accounting.
Recommendation: Either:
Use SafeMath-style operations on uint128, or
Perform explicit overflow checks:
Issue: Some ERC20 tokens do not follow the ERC20 standard correctly and may return false on approve calls. This may lead to approvals silently failing.
Recommendation:
Wrap the approve call with a require statement:
withdrawRewards FunctionIssue: In withdrawRewards(), the function relies on external calls to the vaultController.withdrawOperatorRewards. If the external contract is compromised or reentrancy isn't mitigated, an attacker could drain rewards.
Recommendation:
Use the Checks-Effects-Interactions pattern:
Consider adding the nonReentrant modifier from OpenZeppelin.
Issue: In getPrincipalDeposits() and getRewards(), you call lockingPool.sequencers(seqId). If seqId is 0 or uninitialized, this could lead to invalid reads or unexpected behavior.
Recommendation:
Add a check to ensure seqId != 0 before accessing lockingPool:
Issue: Every deposit updates trackedTotalDeposits using a 128-bit cast and performs relock or lockWithRewardRecipient. If the sequence owner isn't updated often, you could be incurring unnecessary state updates.
Recommendation:
Optimize state updates and batching by reducing redundant writes, e.g., call relock only when needed.
Issue: In updateDeposits(), you allow the contract to transfer any balance back to msg.sender. If malicious ETH is accidentally sent to the contract or if the contract is exploited, this could cause unintended ETH transfers.
Recommendation:
Validate the balance and restrict ETH transfers to trusted actors. You could add a require check:
Issue: The contract uses UUPS proxies, but upgrade authorization relies only on the onlyOwner modifier. If ownership is transferred accidentally or compromised, the upgrade could be exploited.
Recommendation:
Add multi-sig or time-locked upgrade mechanisms to mitigate upgrade risks.
Issue: Some functions like deposit() and updateDeposits() modify critical state without emitting events.
Impact: This reduces the ability to track changes off-chain (important for transparency).
Recommendation: Add events to critical state-changing functions.
| Issue | Recommendation |
|---|---|
| Initialization front-running | Ensure initialization is secured. |
| Missing zero address checks | Add zero address checks in initialize. |
| Arithmetic overflow risks | Add safe math checks for uint128 operations. |
| Unchecked ERC20 approvals | Use require for approve return values. |
Reentrancy in withdrawRewards |
Apply nonReentrant and C-E-I pattern. |
| Getter functions without seqId check | Add require(seqId != 0) checks. |
| Gas inefficiencies in deposit logic | Reduce redundant writes and calls. |
| Unsafe Ether handling | Restrict Ether transfers. |
| UUPS upgrade risks | Use multi-sig or time locks for upgrades. |
| Missing events for state changes | Emit events on critical state changes. |
This code appears well-structured overall, but implementing the above recommendations would improve its security, gas efficiency, and upgrade safety.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.