DCIPs/assets/eip-4671/ERC4671Store.sol

58 lines
2.3 KiB
Solidity

// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "./IERC4671Store.sol";
contract ERC4671Store is IERC4671Store, ERC165 {
// Mapping from owner to IERC4671Enumerable contracts
mapping(address => address[]) private _records;
// Mapping from owner to IERC4671Enumerable contract index
mapping(address => mapping(address => uint256)) _indices;
/// @notice Add a IERC4671Enumerable contract address to the caller's record
/// @param token Address of the IERC4671Enumerable contract to add
function add(address token) public virtual override {
address[] storage contracts = _records[msg.sender];
_indices[msg.sender][token] = contracts.length;
contracts.push(token);
emit Added(msg.sender, token);
}
/// @notice Remove a IERC4671Enumerable contract from the caller's record
/// @param token Address of the IERC4671Enumerable contract to remove
function remove(address token) public virtual override {
uint256 index = _indexOfTokenOrRevert(msg.sender, token);
address[] storage contracts = _records[msg.sender];
if (index == contracts.length - 1) {
_indices[msg.sender][token] = 0;
} else {
_indices[msg.sender][contracts[contracts.length - 1]] = index;
}
contracts[index] = contracts[contracts.length - 1];
contracts.pop();
emit Removed(msg.sender, token);
}
/// @notice Get all the IERC4671Enumerable contracts for a given owner
/// @param owner Address for which to retrieve the IERC4671Enumerable contracts
function get(address owner) public view virtual override returns (address[] memory) {
return _records[owner];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC4671Store).interfaceId ||
super.supportsInterface(interfaceId);
}
function _indexOfTokenOrRevert(address owner, address token) private view returns (uint256) {
uint256 index = _indices[owner][token];
require(index > 0 || _records[owner].length > 0, "Address not found");
return index;
}
}