Assessment reports>SSI Protocol>Medium findings>Incorrect length calculation on ,subTokenset
Category: Coding Mistakes

Incorrect length calculation on subTokenset

Medium Impact
High Severity
Low Likelihood

Description

The function subTokenset implements the subtract operation of token sets:

function subTokenset(Token[] memory a_, Token[] memory b) internal pure returns (Token[] memory) {
    Token[] memory a = copyTokenset(a_);
    uint newLength = a.length;
    uint k;
    for (uint i = 0; i < b.length; i++) {
        k = a.length;
        for (uint j = 0; j < a.length; j++) {
            if (isSameToken(b[i], a[j])) {
                require(a[j].amount >= b[i].amount, "a.amount less than b.amount");
                a[j].amount -= b[i].amount;
                if (a[j].amount == 0) {
                    newLength -= 1;
                }
                k = j;
                break;
            }
        }
        require(k < a.length, "a not contains b");
    }
    Token[] memory res = new Token[](newLength);
    k = 0;
    for (uint i = 0; i < a.length; i++) {
        if (a[i].amount > 0) {
            res[k++] = a[i];
        }
    }
    return res;
}

This function subtracts the token set b from the token set a and returns the result-token set. Internally, it modifies the given token set a with in-place manner, creates a new result-token set array, and then copies the nonzero tokens to the new array.

To calculate the length of the result-token--set array, the function uses the variable newLength. The initial value of this variable is the length of the array a, and this variable decrements when the function finds that subtracting the token leads the element in a to have a zero amount.

However, this logic is not perfect for calculating the length of a result array, because

  • one might include a token with a zero balance in the token set a. While this influences the initial value of newLength, this will not be copied to the result-token set, resulting in an uninitialized token in the array.

  • one might also include a token with a zero balance in the token set a and then duplicates the same zero-balance token in the token set b multiple times. This would reduce the newLength more than the number of the tokens with zero balance, having some tokens omitted in the result-token set.

Impact

The subTokenset function may return the token set with uninitialized tokens or without some tokens.

Recommendations

Consider improving the way newLength is handled or manually calculating the length of the result-token set after the subtraction.

Remediation

This issue has been acknowledged by SoSoValue, and a fix was implemented in commit 7ddd9c5d.

Zellic © 2025Back to top ↑