code-423n4 / 2023-07-amphora-findings

3 stars 2 forks source link

Can mint unlimited amount of WUSDA with 0 USDA #355

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-07-amphora/blob/daae020331404647c661ab534d20093c875483e1/core/solidity/contracts/core/WUSDA.sol#L60

Vulnerability details

Impact

The WUSDA smart contract has a critical vulnerability that allows an attacker to mint an unlimited amount of WUSDA tokens with 0 USDA as collateral.

Proof of Concept

The vulnerability lies in following functions:

function mint(uint256 _wusdaAmount) external override returns (uint256 _usdaAmount) {
    _usdaAmount = _wUSDAToUSDA(_wusdaAmount, _usdaSupply());
    _deposit(_msgSender(), _msgSender(), _usdaAmount, _wusdaAmount);
}

function _wUSDAToUSDA(uint256 _wusdaAmount, uint256 _totalUsdaSupply) private pure returns (uint256 _usdaAmount) {
    _usdaAmount = (_wusdaAmount * _totalUsdaSupply) / MAX_wUSDA_SUPPLY;
}

The _wUSDAToUSDA() function calculates the amount of USDA needed to mint a given amount of WUSDA, based on the _totalUsdaSupply. However, due to an underflow issue, when _totalUsdaSupply is very low (e.g., 1 * 10^18) and _wusdaAmount is large, the _usdaAmount is calculated to be 0.

As a result, an attacker can mint a significant amount of WUSDA with 0 USDA collateral, which can lead to severe economic consequences for the system. The attacker can exploit this to inflate the total supply of WUSDA without providing any actual collateral.

Example

Initial condition:

Suppose Alice sends a mint transaction with _wusdaAmount = 9,999,999, after executing _wUSDAToUSDA() we got:

    _usdaAmount = (9,999,999 * 1 * 10^18) / (10,000,000 * 10^18) = 0

As a result, Alice can mint 9,999,999 WUSDA tokens without providing any USDA collateral.

Impact of the Exploit

This vulnerability allows an attacker to mint an unlimited (upto MAX_wUSDA_SUPPLY) amount of WUSDA tokens without backing them with any collateral. The attacker can exploit this flaw to manipulate the system, causing economic instability and unfair advantages.

Recommended Mitigation Steps

To address this vulnerability, it is crucial to prevent the minting process from proceeding if the calculated _usdaAmount is 0. This can be achieved by adding a requirement in the mint() function:

function mint(uint256 _wusdaAmount) external override returns (uint256 _usdaAmount) {
    _usdaAmount = _wUSDAToUSDA(_wusdaAmount, _usdaSupply());
    require(_usdaAmount > 0, "_usdaAmount equals 0");
    _deposit(_msgSender(), _msgSender(), _usdaAmount, _wusdaAmount);
}

Assessed type

Under/Overflow

c4-pre-sort commented 1 year ago

minhquanym marked the issue as duplicate of #28

c4-judge commented 1 year ago

dmvt marked the issue as satisfactory