The setWeightsManually() function fails to update lastPoolUpdateRun timestamp, allowing attackers to sandwich manual weight updates with performUpdate() calls to profit from price differences.
When trusted accounts (pool manager or quantammAdmin) call setWeightsManually(), the function updates weights but doesn't update lastPoolUpdateRun. This allows:
Attacker observes pending manual weight update and two options are available
He sandwich it immediately in the same txn (current Prices returned by oracles favor the attack)
He waits some blocks till the attack gets profitable and prices spike very high
Buys tokens from pool in multiple small trades (bypassing maxTradeSizeRatio)
Calls performUpdate() which changes weights again
Sells tokens at better rates in same transaction
The block multiplier mechanism reduces but doesn't eliminate the profit opportunity since weights can still change significantly between the manual update and forced update.
The root cause is in setWeightsManually() sepcifically
Financial loss through MEV sandwich attacks
Manipulation of pool weights beyond intended changes
Bypass one of the protective mechanism against volatile price changes (updateInterval)
Manual review
Add timestamp update in setWeightsManually():
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.
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.