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)
}
}
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)