After adding an inactive trader using addSwingTrader(), activeTraders array will contain an inactive trader.
Furthermore, if the inactive trader is toggled to active using toggleTraderActive(), activeTraders array will contain the trader twice and the main functions like buyMalt() and sellMalt() will work wrongly as they assume activeTraders contains traders only once.
Proof of Concept
addSwingTrader() adds new traders with a custom active state.
So traderId will be added to activeTraders array if active = false.
After noticing the trader is inactive, toggleTraderActive() might be called to activate it.
function toggleTraderActive(uint256 traderId)
external
onlyRoleMalt(ADMIN_ROLE, "Must have admin privs")
{
SwingTraderData storage trader = swingTraders[traderId];
require(trader.id == traderId, "Unknown trader");
bool active = !trader.active;
trader.active = active;
if (active) {
// setting it to active so add to activeTraders
trader.index = activeTraders.length;
activeTraders.push(traderId);
} else {
// Becoming inactive so remove from activePools
uint256 index = trader.index;
uint256 lastTrader = activeTraders[activeTraders.length - 1];
activeTraders[index] = lastTrader;
activeTraders.pop();
swingTraders[lastTrader].index = index;
trader.index = 0;
}
emit ToggleTraderActive(traderId, active);
}
Then it will become worse because the same traderId will be added to activeTraders again as active = true.
As a result, activeTraders will contain the same trader twice and it will bring serious problems by using the same trader twice in several functions like buyMalt() and sellMalt().
Tools Used
Manual Review
Recommended Mitigation Steps
We shouldn't add traderId to activeTrader when active = false.
Lines of code
https://github.com/code-423n4/2023-02-malt/blob/main/contracts/StabilityPod/SwingTraderManager.sol#L415
Vulnerability details
Impact
After adding an inactive trader using
addSwingTrader()
,activeTraders
array will contain an inactive trader.Furthermore, if the inactive trader is toggled to active using
toggleTraderActive()
,activeTraders
array will contain the trader twice and the main functions likebuyMalt()
andsellMalt()
will work wrongly as they assumeactiveTraders
contains traders only once.Proof of Concept
addSwingTrader()
adds new traders with a customactive
state.So
traderId
will be added toactiveTraders
array ifactive = false
.After noticing the trader is inactive,
toggleTraderActive()
might be called to activate it.Then it will become worse because the same
traderId
will be added toactiveTraders
again asactive = true
.As a result,
activeTraders
will contain the same trader twice and it will bring serious problems by using the same trader twice in several functions likebuyMalt()
andsellMalt()
.Tools Used
Manual Review
Recommended Mitigation Steps
We shouldn't add
traderId
toactiveTrader
whenactive = false
.