code-423n4 / 2022-02-jpyc-findings

1 stars 0 forks source link

Gas Optimizations #55

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

C4-001 : Use of _msgSender()

Impact

The use of _msgSender() when there is no implementation of a meta transaction mechanism that uses it, such as EIP-2771, very slightly increases gas consumption.

Proof of Concept

_msgSender() is utilized three times where msg.sender could have been used in the following function.

https://github.com/code-423n4/2022-02-jpyc/blob/main/contracts/v1/Ownable.sol#L43

Tools Used

None

Recommended Mitigation Steps

Replace _msgSender() with msg.sender if there is no mechanism to support meta-transactions like EIP-2771 implemented.

C4-002: Adding unchecked directive can save gas

Impact

For the arithmetic operations that will never over/underflow, using the unchecked directive (Solidity v0.8 has default overflow/underflow checks) can save some gas from the unnecessary internal over/underflow checks.

Proof of Concept

  1. Navigate to the following contract. Apply unchecked directive where overflow/underflow is not possible.

https://github.com/code-423n4/2022-02-jpyc/blob/main/contracts/v2/FiatTokenV2.sol#L326

    function _transfer(
        address from,
        address to,
        uint256 value
    ) internal override {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(
            value <= balances[from],
            "ERC20: transfer amount exceeds balance"
        );

        balances[from] = balances[from] - value;
        balances[to] = balances[to] + value;
        emit Transfer(from, to, value);
    }
  1. Consider the all functions. And apply changes regarding to openzeppelin.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L238

Tools Used

None

Recommended Mitigation Steps

Consider applying unchecked arithmetic where overflow/underflow is not possible.

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

C4-003: > 0 can be replaced with != 0 for gas optimization

Impact

!= 0 is a cheaper operation compared to > 0, when dealing with uint.

Proof of Concept

  1. Navigate to the following contracts.
https://github.com/code-423n4/2022-02-jpyc/blob/main/contracts/v2/FiatTokenV2.sol#L143

https://github.com/code-423n4/2022-02-jpyc/blob/main/contracts/v2/FiatTokenV2.sol#L378

Tools Used

Code Review

Recommended Mitigation Steps

Use "!=0" instead of ">0" for the gas optimization.

thurendous commented 2 years ago

C4-001 : Use of _msgSender()

If this is valid, we will fix.

C4-003 and C4-002

This is duplicates of #27 and #2

thurendous commented 2 years ago

C4-001 : Use of _msgSender()

Fixed and thanks!

Final change can be viewed here.