Skip to content

I've added IERC20Allowance and IERC165 #18

Description

@sherpya

I've added support for IERC20Allowance and IERC165, since I'm rather new to yul, I would ask you if the code is ok for a PR.
Also I think it would be nice to add custom errors also in solidity (so they will appear in the abi)

    // first 4 bytes of keccak256("Underflow()") right padded with 0s
    bytes32 internal constant _UNDERFLOW_SELECTOR =
        0xcaccb6d900000000000000000000000000000000000000000000000000000000;

...


    function increaseAllowance(
        address spender,
        uint256 value
    ) external override returns (bool) {
        assembly {
            mstore(0x00, caller())
            mstore(0x20, 0x01)
            mstore(0x20, keccak256(0x00, 0x40))
            mstore(0x00, spender)

            let slot := keccak256(0x00, 0x40)
            let allowance := sload(slot)
            let sum := add(allowance, value)

            if gt(allowance, sum) {
                mstore(0x00, _OVERFLOW_SELECTOR)
                revert(0x00, 0x04)
            }

            //_allowances[msg.sender][spender] += value;
            sstore(slot, sum)

            // emit Approval(msg.sender, spender, sum);
            mstore(0x00, sum)
            log3(0x00, 0x20, _APPROVAL_HASH, caller(), spender)

            // return true;
            mstore(0x00, 0x01)
            return(0x00, 0x20)
        }
    }

    function decreaseAllowance(
        address spender,
        uint256 value
    ) external override returns (bool) {
        assembly {
            mstore(0x00, caller())
            mstore(0x20, 0x01)
            mstore(0x20, keccak256(0x00, 0x40))
            mstore(0x00, spender)

            let slot := keccak256(0x00, 0x40)
            let allowance := sload(slot)
            let diff := sub(allowance, value)

            if gt(diff, allowance) {
                mstore(0x00, _UNDERFLOW_SELECTOR)
                revert(0x00, 0x04)
            }

            //_allowances[msg.sender][spender] -= value;
            sstore(slot, diff)

            // emit Approval(msg.sender, spender, diff);
            mstore(0x00, diff)
            log3(0x00, 0x20, _APPROVAL_HASH, caller(), spender)

            // return true;
            mstore(0x00, 0x01)
            return(0x00, 0x20)
        }
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(
        bytes4 interfaceId
    ) public pure virtual override returns (bool) {
        assembly {
            switch interfaceId
            case 0x01ffc9a700000000000000000000000000000000000000000000000000000000 /* IERC165 */ {
                mstore(0x00, 0x01)
            }
            case 0x36372b0700000000000000000000000000000000000000000000000000000000 /* IERC20 */ {
                mstore(0x00, 0x01)
            }
            case 0x942e8b2200000000000000000000000000000000000000000000000000000000 /* IERC20Metadata */ {
                mstore(0x00, 0x01)
            }
            case 0x9d8ff7da00000000000000000000000000000000000000000000000000000000 /* IERC20Permit */ {
                mstore(0x00, 0x01)
            }
            case 0x9d07518600000000000000000000000000000000000000000000000000000000 /* IERC20Allowance */ {
                mstore(0x00, 0x01)
            }
            default {
                mstore(0x00, 0x00)
            }
            return(0x00, 0x20)
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions