Closed code423n4 closed 1 year ago
0xSorryNotSorry marked the issue as primary issue
non issue, this happens in all ERC20 tokens
ElliotFriedman marked the issue as sponsor disputed
If anyone asserts that the approve front-run vulnerability is valid, I will charge them with contempt of court.
alcueca marked the issue as unsatisfactory: Insufficient proof
Lines of code
https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/MToken.sol#L159-L164 https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/Governance/Well.sol#L89-L101
Vulnerability details
Impact
The current implementation of the approve() function within MToken.sol and Well.sol can potentially be front-runned under a certain set of circumstances. This is a well known bug in ERC20 contracts, and will be explained in detail below. The impact of this scenario is lost user funds. In particular, more mTokens and well tokens can be transferred out of user’s wallets than they intended.
Proof of Concept
The approve() function is called when a user permits the spender to transfer funds (via the transferFrom() function) on their behalf. The vulnerability presents itself when the initial user calls approve() a second time to re-adjust the allowance permitted to be spent. If the spender sees this re-adjustment transaction in the mempool before it gets mined, then the spender will have a brief opportunity to call transferFrom to transfer the initial balance (they can pay high gas fees to make sure their transfer gets mined first). The spender can then receive the original balance that they were permitted to spend, while still getting authorization to transfer the second re-adjusted balance. This would result in lost funds for the initial user.
https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/MToken.sol#L159-L164
https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/Governance/Well.sol#L89-L101
Vulnerability in Steps:
Recommended Mitigation Steps
The solution for both mToken.sol and Well.sol are virtually the same. Both contracts should implement the increaseAllowance and decreaseAllowance functions below.
The two functions for mToken.sol:
The two functions for Well.sol:
Furthermore, the line of code below should also be added as a check inside of the approve() function so that users can only call approve() if they are adding a transfer allowance for the first time. If they need to change this allowance, then users will need to do this via the increaseAllowance() or decreaseAllowance() function. Under this scenario, front running attacks will result in the initial transferAllowance being transferred before the allowance can be changed, but it won’t result in additional mTokens or well tokens being transferred beyond what users initially approved.
Assessed type
ERC20