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);
}