|
@@ -4,10 +4,8 @@ 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 {IERC1363Receiver} from "../../../interfaces/IERC1363Receiver.sol";
|
|
|
-import {IERC1363Spender} from "../../../interfaces/IERC1363Spender.sol";
|
|
|
+import {ERC1363Utils} from "../utils/ERC1363Utils.sol";
|
|
|
|
|
|
/**
|
|
|
* @title ERC1363
|
|
@@ -16,18 +14,6 @@ import {IERC1363Spender} from "../../../interfaces/IERC1363Spender.sol";
|
|
|
* {ERC1363-transferFromAndCall} methods while calls after approvals can be made with {ERC1363-approveAndCall}
|
|
|
*/
|
|
|
abstract contract ERC1363 is ERC20, ERC165, IERC1363 {
|
|
|
- /**
|
|
|
- * @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 Indicates a failure within the {transfer} part of a transferAndCall operation.
|
|
|
* @param receiver Address to which tokens are being transferred.
|
|
@@ -80,7 +66,7 @@ abstract contract ERC1363 is ERC20, ERC165, IERC1363 {
|
|
|
if (!transfer(to, value)) {
|
|
|
revert ERC1363TransferFailed(to, value);
|
|
|
}
|
|
|
- _checkOnTransferReceived(_msgSender(), to, value, data);
|
|
|
+ ERC1363Utils.checkOnERC1363TransferReceived(_msgSender(), _msgSender(), to, value, data);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -112,7 +98,7 @@ abstract contract ERC1363 is ERC20, ERC165, IERC1363 {
|
|
|
if (!transferFrom(from, to, value)) {
|
|
|
revert ERC1363TransferFromFailed(from, to, value);
|
|
|
}
|
|
|
- _checkOnTransferReceived(from, to, value, data);
|
|
|
+ ERC1363Utils.checkOnERC1363TransferReceived(_msgSender(), from, to, value, data);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -139,67 +125,7 @@ abstract contract ERC1363 is ERC20, ERC165, IERC1363 {
|
|
|
if (!approve(spender, value)) {
|
|
|
revert ERC1363ApproveFailed(spender, value);
|
|
|
}
|
|
|
- _checkOnApprovalReceived(spender, value, data);
|
|
|
+ ERC1363Utils.checkOnERC1363ApprovalReceived(_msgSender(), spender, value, data);
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * @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 _checkOnTransferReceived(address from, address to, uint256 value, bytes memory data) private {
|
|
|
- if (to.code.length == 0) {
|
|
|
- revert ERC1363InvalidReceiver(to);
|
|
|
- }
|
|
|
-
|
|
|
- try IERC1363Receiver(to).onTransferReceived(_msgSender(), 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 {
|
|
|
- /// @solidity memory-safe-assembly
|
|
|
- assembly {
|
|
|
- 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 _checkOnApprovalReceived(address spender, uint256 value, bytes memory data) private {
|
|
|
- if (spender.code.length == 0) {
|
|
|
- revert ERC1363InvalidSpender(spender);
|
|
|
- }
|
|
|
-
|
|
|
- try IERC1363Spender(spender).onApprovalReceived(_msgSender(), 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 {
|
|
|
- /// @solidity memory-safe-assembly
|
|
|
- assembly {
|
|
|
- revert(add(32, reason), mload(reason))
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
}
|