Skip to content
Lattice

ERC721WrapperLib

Git Source

Title: ERC721WrapperLib

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/ERC721Wrapper.sol)

Library implementing id-for-id wrapping of an underlying ERC-721. All logic lives here; the facet delegates.

OpenZeppelin keeps the underlying in an immutable; a diamond's facets are shared, so this stores it in the ERC-7201 slot instead. The underlying is trusted, as upstream assumes: depositFor calls it before minting. Mints and burns go straight through ERC721Lib, which has no hook (D25, option (a)), so the movement overrides that Replace the transfer selectors do not see them: ERC721Enumerable and ERC721Votes are mutually exclusive with this extension, and ERC721Pausable does not pause it.

Functions

erc721WrapperStorage

function erc721WrapperStorage() internal pure returns (ERC721WrapperStorage storage $);

Returns

NameTypeDescription
$ERC721WrapperStorage

__ERC721Wrapper_init

Initializes the wrapper with its underlying collection.

Must be called inside a pre/postInitializer block. Like OpenZeppelin, it does not validate underlying_.

function __ERC721Wrapper_init(address underlying_) internal;

Parameters

NameTypeDescription
underlying_address

registerInterface

Registers support for the IERC721Wrapper interface via ERC-165.

function registerInterface() internal;

underlying

The underlying ERC-721 collection being wrapped.

function underlying() internal view returns (address);

Returns

NameTypeDescription
<none>address

depositFor

Pulls each of tokenIds from the caller's underlying balance and safely mints the same id to account.

The pull is an unsafe transferFrom, so it triggers no receiver hook (and so no onERC721Received).

function depositFor(address account, uint256[] memory tokenIds) internal returns (bool);

Parameters

NameTypeDescription
accountaddress
tokenIdsuint256[]

Returns

NameTypeDescription
<none>bool

withdrawTo

Burns each of tokenIds (the caller must own or be approved for it) and safely sends the same underlying id to account.

A non-zero auth makes ERC721Lib._update check authorization and existence, so the previous owner needs no check. The wrapped id is gone before the external call, so the call cannot reuse it.

function withdrawTo(address account, uint256[] memory tokenIds) internal returns (bool);

Parameters

NameTypeDescription
accountaddress
tokenIdsuint256[]

Returns

NameTypeDescription
<none>bool

onERC721Received

Mints the wrapped id to from when the underlying collection safely transfers a token to the diamond.

Reverts IERC721Wrapper.ERC721UnsupportedToken for any caller other than the underlying. Like OpenZeppelin, it ignores data. A plain transferFrom skips this hook; recover covers that case.

function onERC721Received(address, address from, uint256 tokenId, bytes memory) internal returns (bytes4);

Parameters

NameTypeDescription
_address
fromaddress
tokenIduint256
_bytes

Returns

NameTypeDescription
<none>bytes4

recover

Mints the wrapped tokenId to account for an underlying token the diamond holds unwrapped (sent by a plain transferFrom).

Internal — a facet exposing this MUST add access control. Not on the base ERC721Wrapper facet. Reverts IERC721.ERC721IncorrectOwner when the diamond does not own the underlying tokenId.

function recover(address account, uint256 tokenId) internal returns (uint256);

Parameters

NameTypeDescription
accountaddress
tokenIduint256

Returns

NameTypeDescription
<none>uint256