Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always clearApproval on removeNFToken #50 #51

Closed
wants to merge 1 commit into from

Conversation

dafky2000
Copy link
Contributor

@dafky2000 dafky2000 commented May 17, 2018

Fixed #50

@dafky2000
Copy link
Contributor Author

dafky2000 commented May 18, 2018

I just noticed that this could have been exploited via NFTokenEnumerable->removeNFToken as well.

@xpepermint
Copy link
Member

Thanks, @dafky2000. Can you please clarify your last comment?

@dafky2000
Copy link
Contributor Author

dafky2000 commented May 18, 2018

If NFTokenEnumerable is used (NFTokenEnumerableMock for example) and NFTokenEnumerable->removeNFToken is executed, the previous approval will not be removed (without this PR) .

  function removeNFToken(
    address _from,
    uint256 _tokenId
  )
   internal
  {
    super.removeNFToken(_from, _tokenId);
    assert(ownerToIds[_from].length > 0);

    uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId];
    uint256 lastTokenIndex = ownerToIds[_from].length.sub(1);
    uint256 lastToken = ownerToIds[_from][lastTokenIndex];

    ownerToIds[_from][tokenToRemoveIndex] = lastToken;
    ownerToIds[_from][lastTokenIndex] = 0;

    ownerToIds[_from].length--;
    idToOwnerIndex[_tokenId] = 0;
    idToOwnerIndex[lastToken] = tokenToRemoveIndex;
  }

@dafky2000
Copy link
Contributor Author

dafky2000 commented May 18, 2018

So this PR should either be accepted OR change the NFTokenEnumerable->removeNFToken to read

function removeNFToken(
    address _from,
    uint256 _tokenId
  )
   internal
  {
+    clearApproval(_from, _tokenId);
    super.removeNFToken(_from, _tokenId);
    assert(ownerToIds[_from].length > 0);

    uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId];
    uint256 lastTokenIndex = ownerToIds[_from].length.sub(1);
    uint256 lastToken = ownerToIds[_from][lastTokenIndex];

    ownerToIds[_from][tokenToRemoveIndex] = lastToken;
    ownerToIds[_from][lastTokenIndex] = 0;

    ownerToIds[_from].length--;
    idToOwnerIndex[_tokenId] = 0;
    idToOwnerIndex[lastToken] = tokenToRemoveIndex;
  }

@xpepermint
Copy link
Member

We had a long discussion about this small change. Though the proposal is valid it does not follow the single responsibility principle which we try to follow. Private and internal methods are desired to have a single responsibility. Methods clearApproval and removeNFToken are both internal and thus represent helper methods.

It's really up to the developer to make sure his/her code is secure. A developer can always override methods and do bad things :). We decided to update the documentation with a @notice which warns developers to be cautious (e.g. Use this function with caution ...).

@dafky2000 dafky2000 closed this May 18, 2018
@xpepermint
Copy link
Member

@dafky2000 here's the PR: #54

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants