Moonwell - Stormreckson's results

An open lending and borrowing DeFi protocol.

General Information

Platform: Code4rena

Start Date: 24/07/2023

Pot Size: $100,000 USDC

Total HM: 18

Participants: 73

Period: 7 days

Judge: alcueca

Total Solo HM: 8

Id: 267

League: ETH

Moonwell

Findings Distribution

Researcher Performance

Rank: 50/73

Findings: 1

Award: $44.88

QA:
grade-a

🌟 Selected for report: 0

🚀 Solo Findings: 0

  1. https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/Governance/Well.sol#L89-L90

The approve function in this code snippet is typically used by a token holder to grant permission to another address (spender) to spend a certain amount of their tokens on their behalf. It is not necessary for a user to call this function with their own address as the spender parameter in order to spend their own tokens.

In the given code snippet, if a user calls this approve function with their own address as the spender parameter, it will update the allowances mapping for their own address, effectively granting themselves permission to spend a certain amount of their own tokens. However, this is redundant and unnecessary since the user already has full control over their own tokens.

function approve(address spender, uint rawAmount) external returns (bool) { //Check if spender is token owner require(spender != msg.sender, "Self-approval is not allowed"); uint96 amount; if (rawAmount == type(uint).max) { amount = type(uint96).max; } else { amount = safe96(rawAmount, "Well::approve: amount exceeds 96 bits"); } allowances[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true;

}

By adding the require statement, the function will check if the spender address is different from the caller's address (msg.sender). If the condition is not met (i.e., if the spender is the same as the caller), the function will throw an exception and the approval will not be granted.

  1. The WETHRouter contract lacks Input validations

https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/router/WETHRouter.sol#L11-L12

In the mint function, it would be advisable to validate the recipient address to ensure it is a valid address. This can be done by checking that the address is not zero or the address of the contract itself.

https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/router/WETHRouter.sol#L45-L46

In the redeem function, input validation can be applied in the following areas:

  • Validate that mTokenRedeemAmount is not zero or exceeds the balance of the caller's mToken balance.
  • Validate that recipient is a valid Ethereum address.

Adding input validation to these functions can help prevent potential issues such as invalid input values or unintended behavior. -Consider emitting events to allow for better traceability and easier debugging.

3- https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/router/WETHRouter.sol#L45-L46

Checks for Sufficient mToken Balance: The redeem function does not include any checks to ensure that the user has sufficient mToken balance before initiating the transfer.

  • Without proper checks, it could lead to transferring more mToken than the user actually possesses, resulting in undesired behavior.

Fix:

  • Before executing the transfer of mToken, add a check to verify that the user has sufficient balance for the intended redemption.
  • This can be done by calling mToken.balanceOf(msg.sender) and comparing it to the mTokenRedeemAmount parameter.
  • If the balance is insufficient, revert the transaction with an appropriate error message.

4- https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/router/WETHRouter.sol#L45-L46

Authorization Check for mToken Transfer:

  • The contract assumes that the user has already approved the contract to transfer their mToken on their behalf.
  • However, there is no explicit check to verify if the user has granted the necessary allowance to the contract.
  • Without this check, the contract may attempt to transfer mToken without proper authorization, resulting in a failed transaction.

Fix:

  • Prior to attempting the transfer, add a check to verify if the user has granted the necessary allowance to the contract.
  • You can use mToken.allowance(msg.sender, address(this)) to check the allowance granted to the contract.
  • If the allowance is insufficient, revert the transaction with an appropriate error message.

#0 - c4-judge

2023-08-12T18:17:28Z

alcueca marked the issue as grade-a

#1 - ElliotFriedman

2023-08-15T18:24:51Z

this file is out of scope per contest rules

#2 - c4-sponsor

2023-08-15T18:24:54Z

ElliotFriedman marked the issue as sponsor disputed

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter