hiero-ledger / hiero-ledger/hiero-consensus-node
Self-approve NFT causes SPENDER_ACCOUNT_SAME_AS_OWNER
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 407
- Forks
- 226
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 210
Description
### Background
While working on [Transfer events ticket](https://github.com/hiero-ledger/hiero-consensus-node/issues/22615) was found:
- If you are holder of the NFT, you cant self approve it. By doing self-approve you will get `SPENDER_ACCOUNT_SAME_AS_OWNER`
- Here is a [related validation](https://github.com/hiero-ledger/hiero-consensus-node/blob/a7457a7ea17752a5266b1038f8774543aaf6d33c/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/validators/ApproveAllowanceValidator.java#L260)
- This behavior was requested by initial [HIP](https://hips.hedera.com/hip/hip-336)
```
The allowance approval transaction will fail under the following circumstances:
The spender account is the same as the owner’s account.
```
- Seems like because of this behavior:
- ERC721 `proxy transferFrom(address,address,uint256)` [do not require approval](https://github.com/hiero-ledger/hiero-consensus-node/blob/a7457a7ea17752a5266b1038f8774543aaf6d33c/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc721TransferFromCall.java#L125)
- in the same time, classic `transferFromNFT(address,address,address,uint256)` still [require approval](https://github.com/hiero-ledger/hiero-consensus-node/blob/a7457a7ea17752a5266b1038f8774543aaf6d33c/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/ClassicTransfersDecoder.java#L216)
- This lead to a situation when, if you an owner of NFT, you cant transfer it with `transferFromNFT(address,address,address,uint256)`
- Also It is inconsistent that self-approval is allowed for Fungible Tokens but not for NFTs.
- For EVM standard `ERC721` it seems like it is allowed to transfer not approved token, if you are an owner, [openzeppelin-contracts->ERC721.sol->_isAuthorized](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/239795bea728c8dca4deb6c66856dd58a6991112/contracts/token/ERC721/ERC721.sol#L167)
Taking all above into consideration, it seems like we should allow transfer not approved NFT, if you are an owner, for classic `transferFromNFT(address,address,address,uint256)`
Additional questions:
- For `Fungible Token` we have a behavior where:
- `transferToken(address,address,address,int64)` [not requires approve](https://github.com/hiero-ledger/hiero-consensus-node/blob/bda85713b65d98f804780ee3f4a9ed0a3864a663/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/ClassicTransfersDecoder.java#L133)
- `transferFrom(address,address,address,uint256)` [requires approve](https://github.com/hiero-ledger/hiero-consensus-node/blob/bda85713b65d98f804780ee3f4a9ed0a3864a663/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/ClassicTransfersDecoder.java#L197)
- ERC20 `proxy transfer(address,uint256)` [not requires approve](https://github.com/hiero-ledger/hiero-consensus-node/blob/bda85713b65d98f804780ee3f4a9ed0a3864a663/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc20TransfersTranslator.java#L73)
- ERC20 `transferFrom(address,address,uint256)` [requires approve](https://github.com/hiero-ledger/hiero-consensus-node/blob/bda85713b65d98f804780ee3f4a9ed0a3864a663/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc20TransfersTranslator.java#L77)
- So `Fungible Token` behavior is different from what is proposed for `NFT`, should we do something with it?
### Acceptance Criteria
1. Discuss proposed NFT behavior
2. Discuss FT behavior difference
3. Choose the fix strategy
4. Implement the fix
5. Cover with Unit, HAPI, EVM tests
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ApproveAllowanceValidator.java and the NFT and fungible-token transfer entry points linked in ClassicTransfersDecoder.java, Erc721TransferFromCall.java, and Erc20TransfersTranslator.java. Compare the current approval rules with HIP-336 and ERC721 behavior, then determine the fix strategy and validate it with unit, HAPI, and EVM tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- blockchain
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100