I'm trying to work with ERC 721 tokens in such a way that my contract freezes and unfreezes them (based on some conditions) but I'm having trouble wrapping function calls to the ERC 721 token contract address while preserving permissioning from msg.sender - any help much appreciated!

contract 721TokenFreezer{

  function freezeToken(address _tokenToFreezeAddress, uint256 _tokenToFreezeId) {
    // I want to transfer ownership of the 721 token from msg.sender to this smart contract

  function unfreezeToken(address _tokenToFreezeAddress, uint256 _tokenToFreezeId, address _to){
    //I want to send the 721 token to the _to address
  • Please consider to update the title of the question -- the focus seems to be about freezing/unfreezing. Jan 18, 2019 at 1:06
  • Or are you saying that you want a separate custody contract to record the beneficial ownership of incoming tokens? Jan 18, 2019 at 1:07
  • @WilliamEntriken basically, I want my smart contract to take ownership, but I want this to occur through a call on a wrapper function on MY smart contract rather than having the end user call the ERC721 token contract directly. so the transfer call needs to come from my smart contract; freezing it is just incidental to executing the transfer from my smart contract
    – a94
    Jan 18, 2019 at 20:50

2 Answers 2



We are attempting to create an asset locker which will take custody of ERC-721 assets on behalf of beneficial owners and then allow the beneficial owner to take it back out.


pragma solidity 0.5.1;
import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/erc721.sol";
import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/erc721-token-receiver.sol";

contract AssetLocker is ERC721TokenReceiver {
    mapping (address => mapping(uint256 => address)) beneficialOwner;

    function unfreeze(ERC721 nftContract, uint256 tokenId) external {
        require(beneficialOwner[address(nftContract)][tokenId] == msg.sender);
        nftContract.safeTransferFrom(address(this), msg.sender, tokenId);

    // Deposit an asset and start an auction
    function onERC721Received(
        address from,
        uint256 tokenId,
        bytes calldata
        beneficialOwner[msg.sender][tokenId] = from;
        return 0x150b7a02;


⚠️ What you are doing is dangerous, be careful.

ERC-721 tokens can transfer by a variety of means. Also, there are many situations where a transfer might not be successful (throw) or transfer could require payment. Make sure to account for these before deploying anything important.


Resolved! Needed to use

interface ERC721TokenReceiver {
    function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);

and encode my own internal function call in the bytes parameter :) This has been a learning experience


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.