EFCCWEB3 - Logical Flaw in the Calculation of :: amountMTokenWithoutFee within :: _calcAndValidateDeposit Function allowing user to mint more tokens #52
Logical Flaw in the Calculation of :: amountMTokenWithoutFee within :: _calcAndValidateDeposit Function allowing user to mint more tokens
Summary
A critical flaw has been discovered in the _calcAndValidateDeposit function, which is integral to the smart contract's handling of token deposits. The issue pertains to the improper calculation of the amountMTokenWithoutFee variable, a value that represents the net mTokenamount after deducting applicable fees. The current implementation fails to adequately subtract the fee's mToken equivalent from the total mToken amount, resulting in an erroneous amountMTokenWithoutFee value. This oversight has profound implications for the contract's financial operations, potentially leading to users being over-credited in their mToken balances.
Vulnerability Detail
The _calcAndValidateDeposit function is a core component of the contract, responsible for processing user deposits. It performs a series of critical calculations:
Conversion of Token to USD: The function converts the deposited token amount (amountToken) into its USD equivalent (tokenAmountInUsd), considering the token's current exchange rate (tokenInRate).
Fee Calculation: It computes the applicable fee (feeTokenAmount) based on the transaction parameters, which include the sender's address, the token involved, and whether the transaction is an instant operation. The fee is subtracted from the total token amount to yield amountTokenWithoutFee.
Conversion of USD to mToken: The function then converts the net USD amount (after fee deduction) into the equivalent mToken amount (mintAmount), using a conversion rate (tokenOutRate).
Validation of Minimum Deposit Amount: The function checks if the resulting mintAmount meets the minimum mToken deposit requirements. If the user's total mToken balance is zero, an additional check ensures that the first deposit meets a higher minimum threshold.
Final Assignments: The function then assigns the calculated values to the respective variables, readying them for further use in the transaction process.
This oversight leads to a situation where amountMTokenWithoutFee does not accurately represent the mToken amount post-fee deduction.
Steps to produce:
Initial Deposit: A user initiates a deposit of 100 tokens, with a fee rate of 2%. The _calcAndValidateDeposit function converts the tokens to USD, applies the fee, and then calculates the mToken equivalent.
Final Output: The function outputs an inflated amountMTokenWithoutFee, which does not reflect the proper deduction of fees in mToken terms.
The calculation of amountMTokenWithoutFee should closely follow the pattern used for amountTokenWithoutFee. Specifically, after converting the fee amount to its mToken equivalent, this value should be subtracted from the total mToken amount to yield an accurate amountMTokenWithoutFee.
Since fees will not be deducted users will mint more tokens than intended as fee will not be removed from it value.
Two functions calls this internally and the logical bugs affect them every time it would be called uponupon as you can see below:
DeposiitRequest and DepositInstant, however the depositrequest does call _calcAndValidateDeposit but doesn't mint directly to users but just to make a request for a deposit but An admin can call _approveRequest to approve this and mint unintended amount to the user.
function _validateMinAmount(address user, uint256 amountMTokenWithoutFee) <-----------
internal
view
{
require(amountMTokenWithoutFee >= minAmount, "DV: mToken amount < min"); <---------------- No fee taken from minAmount
if (totalMinted[user] != 0) return;
require(
amountMTokenWithoutFee >= minMTokenAmountForFirstDeposit,
"DV: mint amount < min"
);
}
However since there was no fee deduction user gets to mint tokens more than intended as you can see here at line 130.
mToken.mint(user, mintAmount);
Where the MintAmount should have been deducted but it wasn't.
Tool used
Manual Review
Recommendation
Amend the _calcAndValidateDeposit function to properly deduct the fee from the USD equivalent before calculating mintAmount. This ensures that the mTokens minted accurately reflect the amount after fee deduction.
Solution:
Convert the total USD value (tokenAmountInUsd) into mTokens:
EFCCWEB3
High
Logical Flaw in the Calculation of :: amountMTokenWithoutFee within :: _calcAndValidateDeposit Function allowing user to mint more tokens
Summary
A critical flaw has been discovered in the
_calcAndValidateDeposit
function, which is integral to the smart contract's handling of token deposits. The issue pertains to the improper calculation of theamountMTokenWithoutFee
variable, a value that represents the netmToken
amount after deducting applicable fees. The current implementation fails to adequately subtract the fee's mToken equivalent from the total mToken amount, resulting in an erroneousamountMTokenWithoutFee
value. This oversight has profound implications for the contract's financial operations, potentially leading to users being over-credited in their mToken balances.Vulnerability Detail
The _calcAndValidateDeposit function is a core component of the contract, responsible for processing user deposits. It performs a series of critical calculations:
Conversion of Token to USD: The function converts the deposited token amount (amountToken) into its USD equivalent (
tokenAmountInUsd
), considering the token's current exchange rate (tokenInRate).Fee Calculation: It computes the applicable fee (
feeTokenAmount
) based on the transaction parameters, which include the sender's address, the token involved, and whether the transaction is an instant operation. The fee is subtracted from the total token amount to yield amountTokenWithoutFee.Conversion of USD to mToken: The function then converts the net USD amount (after fee deduction) into the equivalent mToken amount (
mintAmount
), using a conversion rate (tokenOutRate
).Validation of Minimum Deposit Amount: The function checks if the resulting
mintAmount
meets the minimum mToken deposit requirements. If the user's total mToken balance is zero, an additional check ensures that the first deposit meets a higher minimum threshold.Final Assignments: The function then assigns the calculated values to the respective variables, readying them for further use in the transaction process.
This oversight leads to a situation where
amountMTokenWithoutFee
does not accurately represent themToken
amount post-fee deduction.Steps to produce: Initial Deposit: A user initiates a deposit of 100 tokens, with a fee rate of 2%. The _calcAndValidateDeposit function converts the tokens to USD, applies the fee, and then calculates the mToken equivalent.
Examine Calculations: Observe that amountTokenWithoutFee is correctly calculated as amountToken - feeTokenAmount. However,
amountMTokenWithoutFee
is incorrectly assigned without subtracting the mToken equivalent of the fee.Final Output: The function outputs an inflated
amountMTokenWithoutFee
, which does not reflect the proper deduction of fees inmToken
terms.The calculation of
amountMTokenWithoutFee
should closely follow the pattern used foramountTokenWithoutFee
. Specifically, after converting the fee amount to its mToken equivalent, this value should be subtracted from the totalmToken
amount to yield an accurateamountMTokenWithoutFee.
Since fees will not be deducted users will mint more tokens than intended as fee will not be removed from it value.
Two functions calls this internally and the logical bugs affect them every time it would be called uponupon as you can see below: DeposiitRequest and DepositInstant, however the depositrequest does call _calcAndValidateDeposit but doesn't mint directly to users but just to make a request for a deposit but An admin can call _approveRequest to approve this and mint unintended amount to the user.
Impact
Users may receive more mTokens than they should.
Code Snippet
DepositInstant
However since there was no fee deduction user gets to mint tokens more than intended as you can see here at line 130.
Where the MintAmount should have been deducted but it wasn't.
Tool used
Manual Review
Recommendation
Amend the
_calcAndValidateDeposit
function to properly deduct the fee from the USD equivalent before calculating mintAmount. This ensures that the mTokens minted accurately reflect the amount after fee deduction.Convert the total USD value (tokenAmountInUsd) into mTokens:
Convert the fee USD value (feeInUsd) into mTokens:
Now, subtract the mToken equivalent of the fee from the total mToken amount: