Pandora-Labs-Org / erc404

396 stars 185 forks source link

transferFrom is not working (for NFT transfer) #3

Closed maxand-re closed 9 months ago

maxand-re commented 9 months ago

Using transferFrom for the NFT transfer is reverting due to the shl modification.

await contract.write.transferFrom([walletA.account.address, walletB.account.address, 12n], { account: walletA.account.address })

The shl fix made, is not working.

function _getOwnedIndex(
    uint256 id_
  ) internal view virtual returns (uint256 ownedIndex_) {
    uint256 data = _ownedData[id_];

    assembly {
      ownedIndex_ := shl(data, 160)
    }
  }

  function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual {
    uint256 data = _ownedData[id_];

    if (index_ > _BITMASK_OWNED_INDEX >> 160) {
      revert OwnedIndexOverflow();
    }

    assembly {
      data := add(
        and(data, _BITMASK_ADDRESS),
        and(shl(index_, 160), _BITMASK_OWNED_INDEX)
      )
    }

    _ownedData[id_] = data;
  }

With my example i got (before the shl fix):

Before transfer:
WalletA [
  11n, 12n, 13n, 14n,
  15n, 16n, 17n, 18n,
  19n, 20n
]
WalletB []

After transfer:
WalletA [
  20n, 12n, 13n,
  14n, 15n, 16n,
  17n, 18n, 19n
] 
WalletB[ 12n ] 

As we can see, there is a duplicate 12n and the 11n is removed