This proposal SRC-7681 delineates the integration of the fungible SRC-20 token contract with the semi-fungible SRC-1155 multi-token standard, enabling cohesive operations between both standards within a single contract framework. It defines a mechanism for combining two token contracts and synchronizing operations between them.
Motivation
Inspired by SRC-7631 Dual Nature Token Pair, which introduced a concept of interlinkable tokens between SRC-20 and SRC-721, a challenge arises due to the duplicated Transfer(address, address, uint256) event, making full compatibility challenging. However, combining SRC-20 and SRC-1155 offers similar benefits of non-fungible token (NFT) fractionalization natively. Here, acquiring SRC-20 tokens could automatically issue SRC-1155 tokens proportionally to the SRC-20 holdings, achieving full compliance with both standards.
Furthermore, analogous to SRC-7631, this proposal allows users to opt out of SRC-1155 mints and transfers during the SRC-20 to SRC-1155 synchronization process.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Overview
Every SRC-7681 MUST implement both SRC20 and SRC1155 interfaces.
SRC-7681 Interface
The SRC-20 contract MUST implement the following interface.
interfaceISRC7681/* is ISRC20, ISRC1155 */{/// The contract MUST contain the following events
/// SRC20 related events
eventTransfer(addressindexed_from,addressindexed_to,uint256_value);eventApproval(addressindexed_owner,addressindexed_spender,uint256_value);/// The contract MUST contain the following events
/// SRC1155 related events
eventTransferSingle(addressindexed_operator,addressindexed_from,addressindexed_to,uint256_id,uint256_value);eventTransferBatch(addressindexed_operator,addressindexed_from,addressindexed_to,uint256[]_ids,uint256[]_values);eventApprovalForAll(addressindexed_owner,addressindexed_operator,bool_approved);eventURI(string_value,uint256indexed_id);/// The contract MAY contain the following functions
/// SRC20 related functions
functionname()publicviewreturns(string);functionsymbol()publicviewreturns(string);functiondecimals()publicviewreturns(uint8);/// The contract MUST contain the following functions
/// SRC20 related functions
functiontotalSupply()publicviewreturns(uint256);functionbalanceOf(address_owner)publicviewreturns(uint256);functiontransfer(address_to,uint256_value)publicreturns(bool);functiontransferFrom(address_from,address_to,uint256_value)publicreturns(bool);functionapprove(address_spender,uint256_value)publicreturns(bool);functionallowance(address_owner,address_spender)publicviewreturns(uint256);/// The contract MUST contain the following functions
/// SRC1155 related functions
functionbalanceOf(address_owner,uint256_id)externalviewreturns(uint256);functionbalanceOfBatch(address[]calldata_owners,uint256[]calldata_ids)externalviewreturns(uint256[]memory);functionsetApprovalForAll(address_operator,bool_approved)external;functionisApprovedForAll(address_owner,address_operator)externalviewreturns(bool);functionsafeTransferFrom(address_from,address_to,uint256_id,uint256_value,bytescalldata_data)external;functionsafeBatchTransferFrom(address_from,address_to,uint256[]calldata_ids,uint256[]calldata_values,bytescalldata_data)external;}
SRC-7681 Skippable Interface
The SRC-7681 contract MAY implement the following interface.
interfaceISRC7681Skippable{/// @dev Emitted when the skip SRC1155 token status of `owner` is changed by any mechanism.
///
/// This initial skip SRC1155 token status for `owner` can be dynamically chosen to
/// be true or false, but any changes to it MUST emit this event.
eventSkipTokenSet(addressindexedowner,boolstatus);/// @dev Returns true if SRC-1155 mints and transfers to `owner` SHOULD be
/// skipped during SRC-20 to SRC-1155 synchronization. Otherwise false.
///
/// This method MAY revert
///
/// If this method reverts:
/// - Interacting code SHOULD interpret `setSkipToken` functionality as
/// unavailable (and hide any functionality to call `setSkipToken`).
/// - The skip SRC1155 token status for `owner` SHOULD be interpreted as undefined.
///
/// Once a true or false value has been returned for a given `owner`,
/// this method MUST NOT revert for the given `owner`.
functiongetSkipToken(addressowner)externalviewreturns(bool);/// @dev Sets the caller's skip SRC1155 token status.
///
/// This method MAY revert
/// (e.g. insufficient permissions, method not supported).
///
/// Emits a {SkipTokenSet} event.
functionsetSkipToken(boolstatus)external;}
Rationale
Implementation Flexibility
This proposal intentionally does not prescribe specific token synchronization logic to allow for diverse implementation strategies and novel use cases, such as one-to-one synchronization or fractionalization of SRC-1155 tokens based on SRC-20 holdings. Developers are afforded the flexibility to determine their synchronization approach, provided it remains fully compliant with the specifications of both token standards.
SRC-1155 Token Skipping
For instances where the owner is a smart contract, setting the skip status to true by default can prevent unnecessary SRC-1155 minting for interactions with contracts like DEXs and lending protocols, thereby potentially reducing gas costs.
Backwards Compatibility
This proposal is fully backward-compatible with the existing SRC-20 and SRC-1155 standards, ensuring that contracts reliant on these standards will continue to function seamlessly.
Security Considerations
Out-of-gas Denial of Service
When user transfers SRC-20 tokens, it can trigger the automatic minting, transfer, or burning of various SRC-1155 tokens. This process can lead to gas expenses that grow linearly with the number of actions O(n) rather than the fixed cost O(1) usually seen with SRC-20 token transactions. Additionally, the mechanism for choosing SRC-1155 token IDs might increase gas expenses further. Therefore, any synchronization strategy needs to account for the potential rise in SRC-1155 associated gas costs to avoid running out of gas, which could result in denial of service situations.
Sennett Lau (@sennett-lau), "SRC-7681: Dual Nature Multi Token Protocol [DRAFT]," Sila Improvement Proposals, no. 7681, April 2024. Available: https://sips.sila.org/SIPS/sip-7681.