MorpheusAI

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

Missing Access Control in Shares Transfer Function Leading to Unauthorized Transfers

Summary

The issue with access control in the transferSharesFrom() function is that it doesn't check whether the caller has been approved to transfer the specified amount of shares from the sender. This could lead to unauthorized transfers.

Vulnerability Details

Here's the problematic part:

function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) external returns (uint256) {
uint256 tokensAmount = getPooledEthByShares(_sharesAmount);
_spendAllowance(_sender, msg.sender, tokensAmount);
_transferShares(_sender, _recipient, _sharesAmount);
return tokensAmount;
}

This function takes a sender address, a recipient address, and a number of shares as parameters. It then calculates the equivalent amount of tokens based on the transferred shares. After that, it attempts to spend the allowance from the sender to the caller (msg.sender). Finally, it transfers the specified number of shares from the sender to the recipient.

The _spendAllowance() function is supposed to deduct the _sharesAmount from the allowance that the _sender has granted to the caller (msg.sender). However, since there is no check to confirm that the caller has an allowance, an attacker could call transferSharesFrom() with any _sender and _recipient addresses.

Here is a possible attack path:
  1. Observe Accounts:
    The attacker observes accounts that have a positive share balance and identifies a target account from which they want to transfer shares.

  2. Set Allowance:
    The attacker sets an allowance for themselves on the target account, specifying the amount of shares they are allowed to transfer. This is typically done through a separate function like approve() in standard ERC20 contracts.

  3. Call transferSharesFrom():
    The attacker calls the transferSharesFrom() function, specifying the target account as the _sender, their own account as the _recipient, and the amount of shares they wish to transfer.

  4. Unauthorized Transfer:
    The contract transfers the specified amount of shares from the target account to the attacker's account, without checking if the attacker was actually approved to do so by the target account.

  5. Repeat the Process:
    The attacker can repeat this process with different accounts and amounts, transferring shares without authorization.

Impact

The issue here is that there's no check to ensure that the caller has been approved to transfer the specified amount of shares from the sender. If a user tries to transfer shares from another account without having been approved, the _spendAllowance() function will still execute, potentially leading to unauthorized transfers.

Tools Used

Manual Review

Recommendations

You could add a check in the transferSharesFrom() function to ensure that the caller has been approved to transfer the specified amount of shares from the sender.

Here's how you could modify the function:

function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) external returns (uint256) {
require(_sharesAmount <= allowance(_sender, msg.sender), "Caller does not have enough allowance to transfer");
uint256 tokensAmount = getPooledEthByShares(_sharesAmount);
_spendAllowance(_sender, msg.sender, tokensAmount);
_transferShares(_sender, _recipient, _sharesAmount);
return tokensAmount;
}

This way, the function will revert if the caller tries to transfer more shares than they are allowed to, preventing unauthorized transfers.

Updates

Lead Judging Commences

inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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