This report highlights a vulnerability where the LSTRewardsSplitterController contract approves the maximum possible token allowance (type(uint256).max) for a splitter without appropriately revoking or managing the allowance. If a malicious or compromised splitter retains control over the allowance after removal, it could drain the contract’s funds. This vulnerability can lead to financial losses for the contract and its participants.
In the LSTRewardsSplitterController contract, the addSplitter function approves the lst token with type(uint256).max, allowing the splitter to use an unlimited amount of tokens. However, the removeSplitter function does not revoke or reduce this allowance until after the splitter has been deleted, leading to a window of opportunity where a compromised or malicious splitter can still use the approved allowance.
This unlimited approval approach can be exploited if the approval is not properly managed, as the approval persists even after the splitter has been removed. If a malicious contract manages to retain the control, it could potentially drain the full approved balance of tokens.
The vulnerability occurs in the following part of the contract:
In the addSplitter function, the maximum possible token allowance is given to the splitter contract using safeApprove. However, if the splitter is later removed using the removeSplitter function, the allowance is only revoked after interacting with the splitter:
This leaves a critical gap where the malicious splitter can still exploit the approved allowance before it is revoked.
Here’s a step-by-step scenario of how the vulnerability can be exploited:
Step 1: A splitter contract is added using the addSplitter function, with the maximum token allowance granted.
Step 2: The removeSplitter function is called to remove the splitter.
Step 3: Before the approval is revoked, the malicious splitter uses the safeApprove allowance to transfer the full balance of lst tokens from the LSTRewardsSplitterController to an attacker-controlled address.
Malicious splitter contract:
Steps to execute exploit:
A malicious splitter is deployed.
addSplitter is called, approving the splitter with type(uint256).max tokens.
The splitter is then removed via removeSplitter.
Before the approval is revoked, the malicious splitter uses transferFrom to transfer the approved tokens.
Below is a sample Hardhat test that demonstrates the vulnerability:
A malicious splitter can drain all the approved tokens in the contract before the allowance is revoked. This can lead to a significant loss of funds, as the maximum token allowance (type(uint256).max) is approved.
This attack would result in substantial financial loss if exploited, potentially draining all the staked tokens or rewards in the contract, and impacting all users relying on the LSTRewardsSplitterController for token management.
Manual review.
Before removing a splitter, ensure that the token allowance is revoked or set to zero before any interactions with the splitter. This reduces the window of time during which a malicious splitter can exploit the contract.
Rather than using safeApprove with type(uint256).max, implement a safer allowance management strategy using safeIncreaseAllowance and safeDecreaseAllowance to provide more controlled token permissions.
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.