Summary
the variable shouldUpdate
determines when to peform update on the SDLPoolCCIPControllerSecondary
, but this variable is only updated when rewards are distributed
function _ccipReceive(Client.Any2EVMMessage memory _message) internal override {
if (_message.data.length == 0) {
uint256 numRewardTokens = _message.destTokenAmounts.length;
address[] memory rewardTokens = new address[](numRewardTokens);
if (numRewardTokens != 0) {
for (uint256 i = 0; i < numRewardTokens; ++i) {
rewardTokens[i] = _message.destTokenAmounts[i].token;
IERC20(rewardTokens[i]).safeTransfer(sdlPool, _message.destTokenAmounts[i].amount);
}
ISDLPoolSecondary(sdlPool).distributeTokens(rewardTokens);
if (ISDLPoolSecondary(sdlPool).shouldUpdate()) shouldUpdate = true;
}
} else {
uint256 mintStartIndex = abi.decode(_message.data, (uint256));
ISDLPoolSecondary(sdlPool).handleIncomingUpdate(mintStartIndex);
}
emit MessageReceived(_message.messageId, _message.sourceChainSelector);
}
Vulnerability Details
updates can only take place after rewards are distributed even if there is pending update on the SDLPoolSecondary
.
Impact
being unable to update even when there is an update greatly slows the protocol and inconveniences users
Tools Used
manual audit
Recommendations
change the function _ccipReceive
to
function _ccipReceive(Client.Any2EVMMessage memory _message) internal override {
if (_message.data.length == 0) {
uint256 numRewardTokens = _message.destTokenAmounts.length;
address[] memory rewardTokens = new address[](numRewardTokens);
if (numRewardTokens != 0) {
for (uint256 i = 0; i < numRewardTokens; ++i) {
rewardTokens[i] = _message.destTokenAmounts[i].token;
IERC20(rewardTokens[i]).safeTransfer(sdlPool, _message.destTokenAmounts[i].amount);
}
ISDLPoolSecondary(sdlPool).distributeTokens(rewardTokens);
}
} else {
uint256 mintStartIndex = abi.decode(_message.data, (uint256));
ISDLPoolSecondary(sdlPool).handleIncomingUpdate(mintStartIndex);
}
if (ISDLPoolSecondary(sdlPool).shouldUpdate()) shouldUpdate = true;
emit MessageReceived(_message.messageId, _message.sourceChainSelector);
}