1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v5.1.0-rc.1) (token/ERC20/utils/ERC1363Utils.sol)
- pragma solidity ^0.8.20;
- import {IERC1363Receiver} from "../../../interfaces/IERC1363Receiver.sol";
- import {IERC1363Spender} from "../../../interfaces/IERC1363Spender.sol";
- /**
- * @dev Library that provides common ERC-1363 utility functions.
- *
- * See https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
- */
- library ERC1363Utils {
- /**
- * @dev Indicates a failure with the token `receiver`. Used in transfers.
- * @param receiver Address to which tokens are being transferred.
- */
- error ERC1363InvalidReceiver(address receiver);
- /**
- * @dev Indicates a failure with the token `spender`. Used in approvals.
- * @param spender Address that may be allowed to operate on tokens without being their owner.
- */
- error ERC1363InvalidSpender(address spender);
- /**
- * @dev Performs a call to {IERC1363Receiver-onTransferReceived} on a target address.
- *
- * Requirements:
- *
- * - The target has code (i.e. is a contract).
- * - The target `to` must implement the {IERC1363Receiver} interface.
- * - The target must return the {IERC1363Receiver-onTransferReceived} selector to accept the transfer.
- */
- function checkOnERC1363TransferReceived(
- address operator,
- address from,
- address to,
- uint256 value,
- bytes memory data
- ) internal {
- if (to.code.length == 0) {
- revert ERC1363InvalidReceiver(to);
- }
- try IERC1363Receiver(to).onTransferReceived(operator, from, value, data) returns (bytes4 retval) {
- if (retval != IERC1363Receiver.onTransferReceived.selector) {
- revert ERC1363InvalidReceiver(to);
- }
- } catch (bytes memory reason) {
- if (reason.length == 0) {
- revert ERC1363InvalidReceiver(to);
- } else {
- assembly ("memory-safe") {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- }
- /**
- * @dev Performs a call to {IERC1363Spender-onApprovalReceived} on a target address.
- *
- * Requirements:
- *
- * - The target has code (i.e. is a contract).
- * - The target `spender` must implement the {IERC1363Spender} interface.
- * - The target must return the {IERC1363Spender-onApprovalReceived} selector to accept the approval.
- */
- function checkOnERC1363ApprovalReceived(
- address operator,
- address spender,
- uint256 value,
- bytes memory data
- ) internal {
- if (spender.code.length == 0) {
- revert ERC1363InvalidSpender(spender);
- }
- try IERC1363Spender(spender).onApprovalReceived(operator, value, data) returns (bytes4 retval) {
- if (retval != IERC1363Spender.onApprovalReceived.selector) {
- revert ERC1363InvalidSpender(spender);
- }
- } catch (bytes memory reason) {
- if (reason.length == 0) {
- revert ERC1363InvalidSpender(spender);
- } else {
- assembly ("memory-safe") {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- }
- }
|