Stale Opal Beaver
Medium
The internalTransfer function is intended to allow transfers to partyB, but the presence of the userNotPartyB modifier prevents this action, causing a denial of service (DoS) for legitimate transfers to other partyB accounts.
According to the updated Symmio 0.8.4, , Internal transfer have been allowed for partyBs. With the new update, partyBs have balance managers expected to constantly monitor and carry Out allocations and dellocations for their users, but due to the continued presence of the modifier, Internal transfer remains exclusive to party A users only which is in complete rebuttal to the updated docs.
The root cause of the vulnerability is the userNotPartyB(user) modifier, which prevents the function from executing if the user is partyB. This contradicts the intended functionality of allowing transfers to partyB.
-The internalTransfer function must be called with a user address that is partyB. -The whenNotInternalTransferPaused condition must be met. -The msg.sender and user must not be suspended or liquidated.
-A user attempts to call the internalTransfer function to transfer funds to partyB. -The function checks the userNotPartyB(user) modifier. -The check fails because the user is partyB. -The transaction reverts, preventing the transfer from occurring.
The aim of the function is to allow partyB users to transfer some of their funds to a different accounts without waiting for Deallocate cooldown. Due to error partyB is denied an expected service and mandated to wait until Deallocate cool down before transferring their funds to other accounts
Here is the code with unexpected modifier
function internalTransfer(
address user,
uint256 amount
) external whenNotInternalTransferPaused userNotPartyB(user) notSuspended(msg.sender) notSuspended(user) notLiquidatedPartyA(user) {
AccountFacetImpl.internalTransfer(user, amount);
emit InternalTransfer(msg.sender, user, AccountStorage.layout().allocatedBalances[user], amount);
emit Withdraw(msg.sender, user, ((amount * (10 ** IERC20Metadata(GlobalAppStorage.layout().collateral).decimals())) / (10 ** 18)));
emit AllocatePartyA(user, amount, AccountStorage.layout().allocatedBalances[user]);
emit AllocatePartyA(user, amount); // For backward compatibility, will be removed in future
emit SharedEvents.BalanceChangePartyA(user, amount, SharedEvents.BalanceChangeType.ALLOCATE);
}
Remove the userNotPartyB modifier or adjust its logic to allow transfers to partyB while still preventing unauthorized actions