123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/ERC1363.sol)
- pragma solidity ^0.8.20;
- import {ERC20} from "../ERC20.sol";
- import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol";
- import {IERC1363} from "../../../interfaces/IERC1363.sol";
- import {ERC1363Utils} from "../utils/ERC1363Utils.sol";
- /**
- * @title ERC1363
- * @dev Extension of {ERC20} tokens that adds support for code execution after transfers and approvals
- * on recipient contracts. Calls after transfers are enabled through the {ERC1363-transferAndCall} and
- * {ERC1363-transferFromAndCall} methods while calls after approvals can be made with {ERC1363-approveAndCall}
- *
- * _Available since v5.1._
- */
- abstract contract ERC1363 is ERC20, ERC165, IERC1363 {
- /**
- * @dev Indicates a failure within the {transfer} part of a transferAndCall operation.
- * @param receiver Address to which tokens are being transferred.
- * @param value Amount of tokens to be transferred.
- */
- error ERC1363TransferFailed(address receiver, uint256 value);
- /**
- * @dev Indicates a failure within the {transferFrom} part of a transferFromAndCall operation.
- * @param sender Address from which to send tokens.
- * @param receiver Address to which tokens are being transferred.
- * @param value Amount of tokens to be transferred.
- */
- error ERC1363TransferFromFailed(address sender, address receiver, uint256 value);
- /**
- * @dev Indicates a failure within the {approve} part of a approveAndCall operation.
- * @param spender Address which will spend the funds.
- * @param value Amount of tokens to be spent.
- */
- error ERC1363ApproveFailed(address spender, uint256 value);
- /// @inheritdoc IERC165
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
- return interfaceId == type(IERC1363).interfaceId || super.supportsInterface(interfaceId);
- }
- /**
- * @dev Moves a `value` amount of tokens from the caller's account to `to`
- * and then calls {IERC1363Receiver-onTransferReceived} on `to`. Returns a flag that indicates
- * if the call succeeded.
- *
- * 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.
- * - The internal {transfer} must succeed (returned `true`).
- */
- function transferAndCall(address to, uint256 value) public returns (bool) {
- return transferAndCall(to, value, "");
- }
- /**
- * @dev Variant of {transferAndCall} that accepts an additional `data` parameter with
- * no specified format.
- */
- function transferAndCall(address to, uint256 value, bytes memory data) public virtual returns (bool) {
- if (!transfer(to, value)) {
- revert ERC1363TransferFailed(to, value);
- }
- ERC1363Utils.checkOnERC1363TransferReceived(_msgSender(), _msgSender(), to, value, data);
- return true;
- }
- /**
- * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
- * and then calls {IERC1363Receiver-onTransferReceived} on `to`. Returns a flag that indicates
- * if the call succeeded.
- *
- * 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.
- * - The internal {transferFrom} must succeed (returned `true`).
- */
- function transferFromAndCall(address from, address to, uint256 value) public returns (bool) {
- return transferFromAndCall(from, to, value, "");
- }
- /**
- * @dev Variant of {transferFromAndCall} that accepts an additional `data` parameter with
- * no specified format.
- */
- function transferFromAndCall(
- address from,
- address to,
- uint256 value,
- bytes memory data
- ) public virtual returns (bool) {
- if (!transferFrom(from, to, value)) {
- revert ERC1363TransferFromFailed(from, to, value);
- }
- ERC1363Utils.checkOnERC1363TransferReceived(_msgSender(), from, to, value, data);
- return true;
- }
- /**
- * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
- * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
- * Returns a flag that indicates if the call succeeded.
- *
- * 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.
- * - The internal {approve} must succeed (returned `true`).
- */
- function approveAndCall(address spender, uint256 value) public returns (bool) {
- return approveAndCall(spender, value, "");
- }
- /**
- * @dev Variant of {approveAndCall} that accepts an additional `data` parameter with
- * no specified format.
- */
- function approveAndCall(address spender, uint256 value, bytes memory data) public virtual returns (bool) {
- if (!approve(spender, value)) {
- revert ERC1363ApproveFailed(spender, value);
- }
- ERC1363Utils.checkOnERC1363ApprovalReceived(_msgSender(), spender, value, data);
- return true;
- }
- }
|