Summary
Inside PriorityPool
, users are tracked with an accounts
array. In the getAccountData
and getAccounts
functions, the entire array is returned, which can result in out-of-gas errors if the accounts array grows too large, causing calls to exceed the block gas limit.
function getAccounts() external view returns (address[] memory) {
@> return accounts;
}
function getAccountData()
external
view
returns (address[] memory, uint256[] memory, uint256[] memory)
{
@> uint256[] memory reSDLBalances = new uint256[]();
@> uint256[] memory queuedBalances = new uint256[]();
for (uint256 i = 0; i < reSDLBalances.length; ++i) {
address account = accounts[i];
reSDLBalances[i] = sdlPool.effectiveBalanceOf(account);
queuedBalances[i] = accountQueuedTokens[account];
}
return (accounts, reSDLBalances, queuedBalances);
}
Impact
Likelihood:
Very unlikely, as the users array is only increased with queued deposits that require a non-zero amount. This limits the users array to different addresses with non-zero amounts queued, making it unlikely to grow large enough to exceed the gas limit.
Impact: Medium
getAccountData
and getAccounts
would always revert, making on-chain data fetching challenging. This would require a workaround to parse deposit events and keep track of accounts off-chain.
Tools Used
Manual review.
Recommendations
In this scenario, pagination can solve the issue.
function getAccountData(uint256 _pageNum, uint256 _pageSize)
external
view
returns (address[] memory, uint256[] memory, uint256[] memory)
{
address[] memory paginatedAccounts = new address[]();
uint256[] memory reSDLBalances = new uint256[]();
uint256[] memory queuedBalances = new uint256[]();
uint256 startIndex = _pageNum * _pageSize;
uint256 endIndex = startIndex + _pageSize;
endIndex = endIndex > accounts.length ? accounts.length : endIndex;
uint256 counter;
for (uint256 i = startIndex; i < endIndex; ++i) {
address account = accounts[i];
paginatedAccounts[counter] = account;
reSDLBalances[counter] = sdlPool.effectiveBalanceOf(account);
queuedBalances[counter] = accountQueuedTokens[account];
counter++;
}
return (paginatedAccounts, reSDLBalances, queuedBalances);
}