code-423n4 / 2023-05-ajna-findings

2 stars 0 forks source link

Integer Overflow/Underflow in function fundTreasury. #420

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-grants/src/grants/GrantFund.sol#L58-L68 https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-grants/src/grants/GrantFund.sol#L62

Vulnerability details

Impact

fundTreasury function in the GrantFund.sol contract is vulnerable to integer overflow if the value of treasury variable is close to the maximum value of a uint256 integer, which is 2^256-1, and a large value of fundingAmount_ is added to it. It is possible for an integer overflow to occur in the fundTreasury function if the treasury variable is not properly checked and updated.

    function fundTreasury(uint256 fundingAmount_) external override {
        IERC20 token = IERC20(ajnaTokenAddress);

        // update treasury accounting
        treasury += fundingAmount_;

        emit FundTreasury(fundingAmount_, treasury);

        // transfer ajna tokens to the treasury
        token.safeTransferFrom(msg.sender, address(this), fundingAmount_);
    }

For example, suppose the treasury variable is already at its maximum value, which is 2^256 - 1, and you add a large value to it without checking for an overflow. In that case, the treasury variable will overflow, and the value will wrap around to zero. As a result, the contract may behave unexpectedly, and the fundTreasury function may not work as intended.

Proof of Concept

Line of code that can lead to integer overflow or underflow is: #L62

treasury += fundingAmount_;

If the value of treasury is close to the maximum value of a uint256 integer, and a large value of fundingAmount_ is added to it, then an integer overflow may occur. This can happen because uint256 variables are limited to a maximum value, and if an operation causes the value to exceed this maximum, the value will wrap around to zero.

Here is an example of how an attacker can exploit this vulnerability:

// set treasury to the maximum value of uint256
treasury = 2**256 - 1;

// call the null function with a large fundingAmount_
null(1);

In this example, the value of treasury is set to the maximum value of uint256, and the fundTreasury function is called with a funding amount of 1. Since treasury + 1 would exceed the maximum value of uint256, the addition operation would cause an integer overflow, and the value of treasury would wrap around to zero.

Tools Used

Manual review, vscode

Recommended Mitigation Steps

In the fundTreasury function, a mechanism should be implemented to check if the value of treasury is close to the maximum value of a uint256 integer before adding fundingAmount_ to it. One way to achieve this is to use the SafeMath library, which provides a safe implementation of mathematical operations that prevents integer overflow or underflow.

The line of code in #L62 that can lead to integer overflow or underflow can be replaced with the following code using the SafeMath library:

treasury = treasury.add(fundingAmount_);

By using the add function from the SafeMath library, integer overflow or underflow can be prevented, and the contract will be more secure.

Assessed type

Under/Overflow

c4-judge commented 1 year ago

Picodes marked the issue as unsatisfactory: Invalid