MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: high
Valid

Multisig participants will lose their rewards, because target address on destination chain is not owner by them

Summary

If a participant in staking is a multisig wallet and tries to claim rewards, a mint message would be sent to Arbutrim chain with the address of the multisig wallet. However multisigs are contracts deployed on chains and that's why destination chain address, which corresponds to source chain address won't be owned by the same person/s

Vulnerability Details

In common case rewards would be sent to some random user who may don't want to refund them.
In the worst case expoiter can deploy contract on the following address and claim MOR tokens.
See Wintermute

Impact

Lost rewards for participants, who use multisig wallets. This is more ofter practice. Also the problem could occur in other account abstraction scenarios.

Tools Used

Manual Review

Recommendations

Make claim function callable only by the owner and let him pass receiver address for the destination chain:

- function claim(uint256 poolId_, address user_) external payable poolExists(poolId_) {
+ function claim(uint256 poolId_, address receiverAddress ) external payable poolExists(poolId_) {
Pool storage pool = pools[poolId_];
PoolData storage poolData = poolsData[poolId_];
- UserData storage userData = usersData[user][poolId_];
+ UserData storage userData = usersData[msg.sender][poolId_];
require(block.timestamp > pool.payoutStart + pool.claimLockPeriod, "DS: pool claim is locked");
uint256 currentPoolRate_ = _getCurrentPoolRate(poolId_);
uint256 pendingRewards_ = _getCurrentUserReward(currentPoolRate_, userData);
require(pendingRewards_ > 0, "DS: nothing to claim");
// Update pool data
poolData.lastUpdate = uint128(block.timestamp);
poolData.rate = currentPoolRate_;
// Update user data
userData.rate = currentPoolRate_;
userData.pendingRewards = 0;
// @audit if user is multisig wallet, rewards would be lost
// @audit also if the caller of the message is multisig, surplus gass would be lost
// Transfer rewards
+ L1Sender(l1Sender).sendMintMessage{value: msg.value}(receiverAddress, pendingRewards_, _msgSender());
emit UserClaimed(poolId_, user_, pendingRewards_);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Users that interact through smart contracts, account abstaction or multisig wallets lose all rewards because they are not the owners of the same addresses on L2

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.