Alert Source Discuss
đźš§ Stagnant Standards Track: SRC

SRC-4524: Safer SRC-20

Extending SRC-20 with SRC165 and adding safeTransfer (like SRC-721 and SRC-1155)

Authors William Schwab (@wschwab)
Created 2021-12-05
Discussion Link https://sila-magicians.org/t/why-isnt-there-an-src-for-safetransfer-for-src20/7604
Requires SIP-20, SIP-165

Abstract

This standard extends SRC-20 tokens with SIP-165, and adds familiar functions from SRC-721 and SRC-1155 ensuring receiving contracts have implemented proper functionality.

Motivation

SIP-165 adds (among other things) the ability to tell if a target recipient explicitly signals compatibility with an SRC. This is already used in the SIPs for NFTs, SRC-721 and SRC-1155. In addition, SIP-165 is a valuable building block for extensions on popular standards to signal implementation, a trend we’ve seen in a number of NFT extensions. This SIP aims to bring these innovations back to SRC-20.

The importance of SIP-165 is perhaps felt most for app developers looking to integrate with a generic standard such as SRC-20 or SRC-721, while integrating newer innovations built atop these standards. An easy example would be token permits, which allow for a one-transaction approval and transfer. This has already been implemented in many popular SRC-20 tokens using the SRC-2612 standard or similar. A platform integrating SRC-20 tokens has no easy way of telling if a particular token has implemented token permits or not. (As of this writing, SRC-2612 does not require SIP-165.) With SIP-165, the app (or contracts) could query supportsInterface to see if the interfaceId of a particular SIP is registered (in this case, SIP-2612), allowing for easier and more modular functions interacting with SRC-20 contracts. It is already common in NFT extensions to include an SIP-165 interface with a standard, we would argue this is at least in part due to the underlying SRC-721 and SRC-1155 standards integrating SIP-165. Our hope is that this extension to SRC-20 would also help future extensions by making them easier to integrate.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

In order to be compliant with this SIP, and SRC-20-compliant contract MUST also implement the following functions:

pragma solidity 0.8.10;

import './ISRC20.sol';
import './ISRC165.sol';

// the SIP-165 interfaceId for this interface is 0x534f5876

interface SaferERC-20 is ISRC20, ISRC165 {
  function safeTransfer(address to, uint256 amount) external returns(bool);
  function safeTransfer(address to, uint256 amount, bytes memory data) external returns(bool);
  function safeTransferFrom(address from, address to, uint256 amount) external returns(bool);
  function safeTransferFrom(address from, address to, uint256 amount, bytes memory data) external returns(bool);
}

safeTransfer and safeTransferFrom MUST transfer as expected to EOA addresses, and to contracts implementing SRC20Receiver and returning the function selector (0x4fc35859) when called, and MUST revert when transferring to a contract which either does not have SRC20Receiver implemented, or does not return the function selector when called.

In addition, a contract accepting safe transfers MUST implement the following if it wishes to accept safe transfers, and MUST return the function selector (0x4fc35859):

pragma solidity 0.8.10;

import './ISRC165.sol';

interface SRC20Receiver is ISRC165 {
  function onSRC20Received(
    address _operator,
    address _from,
    uint256 _amount,
    bytes _data
  ) external returns(bytes4);
}

Rationale

This SIP is meant to be minimal and straightforward. Adding SIP-165 to SRC-20 is useful for a number of applications, and outside of a minimal amount of code increasing contract size, carries no downside. The safeTransfer and safeTransferFrom functions are well recognized from SRC-721 and SRC-1155, and therefore keeping identical naming conventions is reasonable, and the benefits of being able to check for implementation before transferring are as useful for SRC-20 tokens as they are for SRC-721 and SRC-1155.

Another easy backport from SIP721 and SIP1155 might be the inclusion of a metadata URI for tokens, allowing them to easily reference logo and other details. This has not been included, both in order to keep this SIP as minimal as possible, and because it is already sufficiently covered by SIP-1046.

Backwards Compatibility

There are no issues with backwards compatibility in this SIP, as the full suite of SRC-20 functions is unchanged.

Test Cases

Test cases have been provided in the implementation repo here.

Reference Implementation

A sample repo demonstrating an implementation of this SIP has been created here. It is (as of this writing) in a Dapptools environment, for details on installing and running Dapptools see the Dapptools repo.

Security Considerations

onSRC20Received is a callback function. Callback functions have been exploited in the past as a reentrancy vector, and care should be taken to make sure implementations are not vulnerable.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

William Schwab (@wschwab), "SRC-4524: Safer SRC-20 [STAGNANT]," Sila Improvement Proposals, no. 4524, December 2021. Available: https://sips.sila.org/SIPS/sip-4524.