In the BackingManager, a Dutch trade can be blocked until the tradeEnd time.
The tradeEnd was not updated after settling the Dutch trade.
Mitigation
This issue is correctly mitigated by setting the tradeEnd to the current block.timestamp when settling the Dutch trade.
function settleTrade(IERC20 sell) public override(ITrading, TradingP1) returns (ITrade trade) {
delete tokensOut[sell];
trade = super.settleTrade(sell); // nonReentrant
TradeKind kind = trade.KIND();
if (tradeEnd[kind] > block.timestamp) tradeEnd[kind] = uint48(block.timestamp); // @audit, here
// if the settler is the trade contract itself, try chaining with another rebalance()
if (_msgSender() == address(trade)) {
// solhint-disable-next-line no-empty-blocks
try this.rebalance(trade.KIND()) {} catch (bytes memory errData) {
// prevent MEV searchers from providing less gas on purpose by reverting if OOG
// untested:
// OOG pattern tested in other contracts, cost to test here is high
// see: docs/solidity-style.md#Catching-Empty-Data
if (errData.length == 0) revert(); // solhint-disable-line reason-string
}
}
}
Lines of code
Vulnerability details
In the
BackingManager
, aDutch trade
can be blocked until thetradeEnd
time. ThetradeEnd
was not updated after settling theDutch trade
.Mitigation
This issue is correctly mitigated by setting the
tradeEnd
to the currentblock.timestamp
when settling theDutch trade
.This change does not affect
Batch trades
.