DCIPs/assets/eip-4987/Consumer.sol

85 lines
1.9 KiB
Solidity

/*
Consumer
SPDX-License-Identifier: CC0-1.0
*/
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./IERC721Holder.sol";
/**
* @title Consumer
*
* @notice this contract implements an example "consumer" of the proposed
* held token ERC standard.
* This example consumer contract will query ERC721 ownership and balances
* including any "held" tokens
*/
contract Consumer {
using Address for address;
// members
IERC721 public token;
/**
* @param token_ address of ERC721 token
*/
constructor(address token_) {
token = IERC721(token_);
}
/**
* @notice get the functional owner of a token
* @param tokenId token id of interest
*/
function getOwner(uint256 tokenId) external view returns (address) {
// get raw owner
address owner = token.ownerOf(tokenId);
// if owner is not contract, return
if (!owner.isContract()) {
return owner;
}
// check for token holder interface support
try IERC165(owner).supportsInterface(0x16b900ff) returns (bool ret) {
if (!ret) return owner;
} catch {
return owner;
}
// check for held owner
try IERC721Holder(owner).heldOwnerOf(address(token), tokenId) returns (address user) {
if (user != address(0)) return user;
} catch {}
return owner;
}
/**
* @notice get the total user balance including held tokens
* @param owner user address
* @param holders list of token holder addresses
*/
function getBalance(address owner, address[] calldata holders)
external
view
returns (uint256)
{
// start with raw token balance
uint256 balance = token.balanceOf(owner);
// consider each provided token holder contract
for (uint256 i = 0; i < holders.length; i++) {
balance += IERC721Holder(holders[i]).heldBalanceOf(address(token), owner);
}
return balance;
}
}