-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #28 from superform-xyz/readme-update
chore: clean readme
- Loading branch information
Showing
1 changed file
with
15 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,29 @@ | ||
# ERC1155A - SuperForm's ERC-1155 Extension | ||
# Overview | ||
|
||
SuperForm implementation of ERC-1155 with extended approval logic. Allows token owners to execute single id approvals in place of mass approving all of the ERC-1155 ids to the spender. | ||
ERC1155A is an extension of ERC-1155 with extended approval and transmute logic, used in SuperPositions. This allows token owners to execute single id or multiple id approvals in place of mass approving all of the ERC1155 ids to the spender and to transmute ERC1155 ids to and from registered ERC20's. | ||
|
||
You need foundry/forge to run repository. | ||
|
||
`forge install` | ||
|
||
`forge test` | ||
|
||
Two set of tests are run. `ERC1155A` specific and general `ERC1155` tests forked from solmate's implementation of the standard. SuperForm's `ERC1155A` has exactly the same interface as standard `ERC1155` and expected behavior of functions follow EIP documentation. | ||
|
||
# Rationale | ||
|
||
ERC1155 `setApprovalForAll` function gives full spending permissions over all currently exisiting and future Ids. Addition of single Id approve, allows this token standard to improve composability through more better allowance control of funds. If external contract is an expected to spend only a single ERC1155 id there is no reason it should have access to all the user owned ids. | ||
|
||
# Implementation Details | ||
|
||
Main change is how `ERC1155A` implements `safeTransferFrom()` function. Standard ERC-1155 implementations are checking only if caller `isApprovedForAll` or an owner of token ids. We propose `setApprovalForOne()` function allowing approvals for specific id in any amount. Therefore, id owner is no longer required to mass approve all of his token ids. The side effect of it is requirement of additional validation logic inside of `safeTransferFrom()` function. | ||
Read more about ERC1155 here: https://docs.superform.xyz/periphery-contracts/superpositions/erc1155a | ||
|
||
With gas effiency in mind and preservation of expected ERC1155 behavior, ERC1155A still prioritizes `isApprovedForAll` over `setApprovalForOne()`. Only `safeTransferFrom()` function works with single allowances, `safeBatchTransferFrom()` function requires owner to grant `setApprovalForAll()` to the operator. Decision is dictated by a significant gas costs overhead when required to decrease (or reset, in case of an overflow) allowances for each id in array. Moreover, if owner has `setApprovalForAll()` set to `true`, ERC1155A contract will not modify existing single allowances during `safeTransferFrom()` and `safeBatchTransferFrom()` - assuming that owner has full trust in _operator_ for granting mass approve. Therefore, ERC1155A requires owners to manage their allowances individually and be mindfull of enabling `setApprovalForAll()` for external contracts. | ||
## Rationale | ||
|
||
# Allowances Flow of Execution | ||
ERC1155 `setApprovalForAll` function gives full spending permissions over all currently exisiting and future Ids. Addition a of single Id approve allows this token standard to improve composability through more better allowance control of funds. If external contract is an expected to spend only a single ERC1155 id there is no reason it should have access to all the user owned ids. | ||
|
||
Case 1: AllApproval + NO SingleApproval (standard 1155) | ||
ERC1155s additionally do not provide large composability with the DeFi ecosystem, so we provide the ability to transmute individual token ids via `transmuteToaERC20` to an ERC20 token. This may be reversed via `transmuteToERC1155A`. | ||
|
||
Case 2: AllApproval + SingleApproval _(smaller than amount requested for transfer)_ | ||
## Implementation Details | ||
|
||
Case 3: SingleApproval _(bigger than amount requested for transfer)_ + AllApproval | ||
The main change in approval logic is how ERC1155A implements the `safeTransferFrom()` function. Standard ERC1155 implementations only check if the caller in `isApprovedForAll` is an owner of token ids. We propose `setApprovalForOne()` or `setApprovalForMany()` function allowing approvals for specific id in any amount. Therefore, id owner is no longer required to mass approve all of his token ids. The side effect of it is requirement of additional validation logic inside of `safeTransferFrom()` function. | ||
|
||
Case 4: SingleApproval + NO AllApproval _(ERC20-like)_ | ||
With gas effiency in mind and preservation of expected ERC1155 behavior, ERC1155A still prioritizes `isApprovedForAll` over `setApprovalForOne()`. Only `safeTransferFrom()` function works with single allowances, `safeBatchTransferFrom()` function requires owner to grant `setApprovalForAll()` to the operator. Decision is dictated by a significant gas costs overhead when required to decrease (or reset, in case of an overflow) allowances for each id in array. Moreover, if owner has `setApprovalForAll()` set to `true`, ERC1155A contract will not modify existing single allowances during `safeTransferFrom()` and `safeBatchTransferFrom()` - assuming that owner has full trust in _operator_ for granting mass approve. Therefore, ERC1155A requires owners to manage their allowances individually and be mindful of enabling `setApprovalForAll()` for external contracts. | ||
|
||
Therefore, the possible execution flow with two independent set of approvals is as follows: | ||
ERC1155A token ids may also be transmuted into ERC20's, and transmuted back from the ERC20 through `transmute` functions after `registeraERC20` has been called to create the ERC20 token representation on the chain. | ||
|
||
If caller is owner of ids, transfer just executes. | ||
### Testing | ||
|
||
If caller `singleApproved > transferAmount`, function executes and reduces allowance (even if setApproveForAll is true) | ||
|
||
If caller `singleApproved < transferAmount && isApprovedForAll`, function executes without reducing allowance (full trust assumed) | ||
|
||
If caller only approvedForAll, function executes without reducing allowance (full trust assumed) | ||
|
||
### Gas Overhead | ||
|
||
Additional approval logic validation makes SOME transfer operations more expensive. Here's how it looks by comparison to solmate ERC1155 standard implementation: | ||
|
||
ERC1155A | ||
|
||
``` | ||
| safeBatchTransferFrom | 79432 | 79432 | 79432 | 79432 | 1 | | ||
| safeTransferFrom | 27614 | 31069 | 31801 | 34517 | 5 | | ||
| setApprovalForAll | 24574 | 24574 | 24574 | 24574 | 3 | | ||
| setApprovalForOne | 24920 | 24920 | 24920 | 24920 | 4 | | ||
``` | ||
|
||
ERC-1155 | ||
You need foundry/forge to run repository. | ||
|
||
``` | ||
| safeBatchTransferFrom | 1247 | 896149 | 124953 | 8597031 | 15 | | ||
| safeTransferFrom | 1072 | 34106 | 27191 | 183333 | 18 | | ||
| setApprovalForAll | 4581 | 23615 | 24481 | 24481 | 23 | | ||
``` | ||
`forge install` | ||
|
||
# Future Work | ||
`forge test` | ||
|
||
TODO: https://eips.ethereum.org/EIPS/eip-1761 (suggested by 1155) - range-based approvals | ||
Two set of tests are run. `ERC1155A` specific and general `ERC1155` tests forked from solmate's implementation of the standard. SuperForm's `ERC1155A` has exactly the same interface as standard `ERC1155` and expected behavior of functions follow EIP documentation. |