Uniswap V3 LP NFT Wrapper

Structure of NaftaWrapper

First of all, NaftaWrapper is an ERC721 NFT itself, and also it should comply with IFlashNFTReceiver interface, so that Nafta contract can use it for Flashloans.

A Wrapper should be able to wrap and unwrap the NFTs that are fed to it, and give back WrapperNFTs:

/// @notice Wraps Uniswap V3 NFT
/// @param tokenId The ID of the uniswap nft (minted wrappedNFT will have the same ID)
function wrap(uint256 tokenId) external {
  nftOwners[tokenId] = msg.sender;
  _safeMint(msg.sender, tokenId);
  IERC721(uniV3Address).safeTransferFrom(msg.sender, address(this), tokenId);
}

/// @notice Unwraps Uniswap V3 NFT
/// @param tokenId The ID of the uniswap nft (minted wrappedNFT has the same ID)
function unwrap(uint256 tokenId) external {
  require(nftOwners[tokenId] == msg.sender, "Only owner can unwrap NFT");
  require(ownerOf(tokenId) == msg.sender, "You must hold wrapped NFT to unwrap");
  _burn(tokenId);
  IERC721(uniV3Address).safeTransferFrom(address(this), msg.sender, tokenId);
}

Notice we keep track of who wrapped the NFT with nftOwners - cause otherwise we wouldn’t know who can unwrap it (the owner() wouldn’t work here - cause when you flashLoan - you become an owner).

Then we have our payload function, that allows some useful action on the wrapped NFT, in our case - the extraction of fees:

And finally, we have a standard IFlashNFTReceiver.executeOperation() function, that will be called by Nafta on any FlashLoan act:

And that’s it!

As a bonus and as a UX convenience feature, we also have combined wrapAndAddToNafta() and unwrapAndRemoveFromNafta() functions that save our users the count of transactions they have to make by automatically adding the wrapped NFT to Nafta Pool (or removing it and unwrapping). This is not a requirement, but for sure a nice addition.

Last updated

Was this helpful?