40,000 USDC
View results
Submission Details
Severity: gas

Calling balanceOf in resolveDispute twice wastes gas as the needed variables to calculate the amount already in memory

Summary

The balance of the contract in the specified token as well as the fee for the arbiter and the buyer award is already in memory inside the resolveDispute function. Therefore it is not necessary to call the token contract again, as a simple subtraction will lead to the same result.

Vulnerability Details

The resolveDispute function calls balanceOf and calculates the sum of the buyerAward + the arbiterFee:

function resolveDispute(uint256 buyerAward) external onlyArbiter nonReentrant inState(State.Disputed) {
uint256 tokenBalance = i_tokenContract.balanceOf(address(this));
uint256 totalFee = buyerAward + i_arbiterFee; // Reverts on overflow

After that the buyerAward is transfered to the buyer and the arbiterFee is transfered to the arbiter.

To transfer the rest of the funds inside the contract to the seller, the balanceOf function is called again:

tokenBalance = i_tokenContract.balanceOf(address(this));
if (tokenBalance > 0) {
i_tokenContract.safeTransfer(i_seller, tokenBalance);
}

This is not necessary as tokenBalance - totalFee should result in the same amount and save gas as no external call which reads from the storage of another contract is needed.

The only possibility that would result in different amounts would be if the tokenContract is an ERC-777 token that triggers a hook on any of the transfer functions, which sends more tokens to the contract. However, since this is not the recommended way how to use the protocol, it should not be assumed and therefore gas can be saved.

Impact

Gas is wasted.

Tools Used

Manual Review, Foundry, VSCode

Recommendations

Calculate the amount that should go to the seller by calculating the tokenBalance - totalFee.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.