Malicious users can front-run the removeSplitter
function to transfer 1 wei lst token to the LSTRewardsSplitter
and then the removeSplitter function will revert
In removeSplitter
function, if the balance of LST
tokens is not equal to principalDeposits
, the function calls splitter.splitRewards()
:
The splitRewards
function will distribute some of the currently held LST tokens to the fee receivers:
However, after this distribution, the remaining balance of the LSTRewardsSplitter
contract could be lower than the balance that was originally retrieved and intended for withdrawal.
When calling withdraw(balance, _account)
, if the balance has decreased due to the distribution of fees/withdrawals, this could result in an issue since the splitter will now attempt to withdraw more tokens than it has.
As a result, a malicious user can exploit the logic of the removeSplitter
function by front-running it and transferring 1 wei LST token to LSTRewardsSplitter
contract, effectively ensuring that the withdrawal logic fails due to an unexpected balance change in the LSTRewardsSplitter
.
Here's how the exploit can occur in a sequence of steps:
Observe the Blockchain State:
A malicious user observes the blockchain and sees that an owner is about to call the removeSplitter
function for a specific splitter. They can predict or monitor the transaction and its subsequent effects on the balance.
Transfer 1 Wei LST:
Just before (or at the same time as) the owner's transaction executes, the malicious actor submits a transaction that transfers 1 wei of LST tokens directly to the LSTRewardsSplitter
contract. This can be done using an ERC20
transfer method.
Call to removeSplitter
Execution:
The owner’s transaction calls removeSplitter
, which follows the logic of first checking the balance of the splitter.
If the balance was, for example, 100e18 LST during the initial balance check, this would allow the owner to assume they can withdraw this full amount.
Effect of Front-Run:
With the addition of the 1 wei token from the malicious user, the balance might now read as (100e18+1) wei.
The function may then call splitter.splitRewards()
if needed, which could alter the balance further.
Withdrawal Error:
The withdraw
function will fail because it tries to transfer the entire originally retrieved amount , but because of the misalignment caused by the front-run transaction and potential adjustments during splitRewards
, it results in an insufficient balance state for the intended withdrawal.
Malicious users can dos removeSplitter
function with a small or close to 0 capital cost.
Manual Review
Consider following fix:
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.