Here is a security review of the provided smart contract. Below are potential vulnerabilities and areas of improvement:
initialize() and setRouter()Issue: The contract sets approve() for LINK and METIS tokens with type(uint256).max without controlling approvals in detail.
Risk: If the router’s address is compromised or changed to a malicious contract, the tokens might be stolen.
Mitigation:
Reset approvals to 0 before re-approving large amounts to prevent front-running attacks.
Use OpenZeppelin’s SafeApprove to mitigate approval race conditions:
initialize() ParametersIssue: In the initialize() function, parameters like _router, _linkToken, and _metisToken are not checked for the zero address (except router during conditionals).
Risk: A misconfiguration might lead to unusable or insecure deployments.
Mitigation:
Add zero-address checks for all essential parameters:
transferRewards()Issue: The transferRewards() function could be called repeatedly by the authorized initiator, draining all rewards unexpectedly.
Risk: A malicious or compromised transfer initiator could rapidly deplete rewards through spamming.
Mitigation:
Implement time-based limits or circuit breakers to control how often transfers can occur.
Issue: The onlyTransferInitiator modifier enforces authorization, but once set, the initiator has complete control over reward transfers.
Risk: If the transfer initiator’s key is compromised, all funds could be transferred to a malicious destination.
Mitigation:
Allow the owner to pause transfers in emergencies or implement multisig controls for setting critical parameters.
Add a pause() / unpause() mechanism with OpenZeppelin’s PausableUpgradeable.
_maxLINKFeeIssue: The transferRewards() function allows a transfer only if the LINK fee is below _maxLINKFee. However, the fee might change between the time the transaction is submitted and executed, leading to a front-running vulnerability.
Risk: The transaction might be unexpectedly reverted due to fluctuating fees.
Mitigation:
Consider adding a buffer range or an upper-bound margin for fees to reduce this risk.
Issue: Changes to sensitive parameters like the router address or transfer initiator do not emit events.
Risk: Hard to track changes and detect malicious behavior.
Mitigation:
Emit events when sensitive parameters are updated:
Issue: If tokens other than LINK or METIS are accidentally sent to the contract, they might be locked.
Risk: Inaccessible funds might accumulate over time.
Mitigation:
Add a rescueTokens() function for the owner:
Issue: With UUPS proxies, storage layout mismatches during upgrades can introduce vulnerabilities or unexpected behavior.
Risk: Incorrect upgrades could brick the contract.
Mitigation:
Ensure proper storage layout management and careful upgrade testing.
Add access control checks or restrictions on the _authorizeUpgrade() function:
| Issue | Risk Level | Mitigation |
|---|---|---|
| Unchecked approvals | Medium | Use safeApprove() |
| Missing parameter validation | Medium | Check for zero addresses |
| No rate-limiting for rewards transfer | High | Add throttling/circuit breaker |
| Abuse by authorized initiator | High | Add pause mechanism |
Front-running on _maxLINKFee |
Medium | Add fee buffer |
| No events for critical updates | Low | Emit events for changes |
| Locked tokens without recovery function | Low | Add rescueTokens() |
| Storage collision in UUPS upgrades | Medium | Proper storage management |
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.