编译器
0.8.23+commit.f704f362
文件 1 的 6:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 6:EFPListRecords.sol
pragma solidity ^0.8.23;
import {Ownable} from 'lib/openzeppelin-contracts/contracts/access/Ownable.sol';
import {Pausable} from 'lib/openzeppelin-contracts/contracts/security/Pausable.sol';
import {IEFPListMetadata, IEFPListRecords} from './interfaces/IEFPListRecords.sol';
import {ENSReverseClaimer} from './lib/ENSReverseClaimer.sol';
abstract contract ListMetadata is IEFPListMetadata, Pausable, Ownable {
error SlotAlreadyClaimed(uint256 slot, address manager);
mapping(uint256 => mapping(string => bytes)) private values;
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
function bytesToAddress(bytes memory b) internal pure returns (address) {
require(b.length == 20, 'Invalid length');
address addr;
assembly {
addr := mload(add(b, 20))
}
return addr;
}
function getMetadataValue(uint256 tokenId, string calldata key) external view returns (bytes memory) {
return values[tokenId][key];
}
function getMetadataValues(uint256 tokenId, string[] calldata keys) external view returns (bytes[] memory) {
uint256 length = keys.length;
bytes[] memory result = new bytes[](length);
for (uint256 i = 0; i < length;) {
string calldata key = keys[i];
result[i] = values[tokenId][key];
unchecked {
++i;
}
}
return result;
}
function _setMetadataValue(uint256 slot, string memory key, bytes memory value) internal {
values[slot][key] = value;
emit UpdateListMetadata(slot, key, value);
}
function setMetadataValue(uint256 slot, string calldata key, bytes calldata value)
external
whenNotPaused
onlyListManager(slot)
{
_setMetadataValue(slot, key, value);
}
function _setMetadataValues(uint256 slot, KeyValue[] calldata records) internal {
uint256 length = records.length;
for (uint256 i = 0; i < length;) {
KeyValue calldata record = records[i];
_setMetadataValue(slot, record.key, record.value);
unchecked {
++i;
}
}
}
function setMetadataValues(uint256 slot, KeyValue[] calldata records) external whenNotPaused onlyListManager(slot) {
_setMetadataValues(slot, records);
}
modifier onlyListManager(uint256 slot) {
bytes memory existing = values[slot]['manager'];
if (existing.length != 20) {
_claimListManager(slot, msg.sender);
} else {
address existingManager = bytesToAddress(existing);
if (existingManager == address(0)) {
_claimListManager(slot, msg.sender);
} else {
require(existingManager == msg.sender, 'Not list manager');
}
}
_;
}
function _claimListManager(uint256 slot, address manager) internal {
bytes memory existing = values[slot]['manager'];
if (existing.length == 20) {
address existingManager = bytesToAddress(existing);
if (existingManager != manager) {
revert SlotAlreadyClaimed(slot, existingManager);
}
}
_setMetadataValue(slot, 'manager', abi.encodePacked(manager));
}
function claimListManager(uint256 slot) external whenNotPaused {
_claimListManager(slot, msg.sender);
}
function claimListManagerForAddress(uint256 slot, address manager) external whenNotPaused {
_claimListManager(slot, manager);
}
function getListManager(uint256 slot) external view returns (address) {
bytes memory existing = values[slot]['manager'];
return existing.length != 20 ? address(0) : bytesToAddress(existing);
}
function setListManager(uint256 slot, address manager) external whenNotPaused onlyListManager(slot) {
_setMetadataValue(slot, 'manager', abi.encodePacked(manager));
}
function getListUser(uint256 slot) external view returns (address) {
bytes memory existing = values[slot]['user'];
return existing.length != 20 ? address(0) : bytesToAddress(existing);
}
function setListUser(uint256 slot, address user) external whenNotPaused onlyListManager(slot) {
_setMetadataValue(slot, 'user', abi.encodePacked(user));
}
}
abstract contract ListRecords is IEFPListRecords, ListMetadata {
mapping(uint256 => bytes[]) public listOps;
function getListOpCount(uint256 slot) external view returns (uint256) {
return listOps[slot].length;
}
function getListOp(uint256 slot, uint256 index) external view returns (bytes memory) {
return listOps[slot][index];
}
function getListOpsInRange(uint256 slot, uint256 start, uint256 end) external view returns (bytes[] memory) {
if (start > end) {
revert('Invalid range');
}
bytes[] memory ops = new bytes[](end - start);
for (uint256 i = start; i < end;) {
ops[i - start] = listOps[slot][i];
unchecked {
++i;
}
}
return ops;
}
function getAllListOps(uint256 slot) external view returns (bytes[] memory) {
return listOps[slot];
}
function _applyListOp(uint256 slot, bytes calldata op) internal {
listOps[slot].push(op);
emit ListOp(slot, op);
}
function applyListOp(uint256 slot, bytes calldata op) external whenNotPaused onlyListManager(slot) {
_applyListOp(slot, op);
}
function _applyListOps(uint256 slot, bytes[] calldata ops) internal {
uint256 len = ops.length;
for (uint256 i = 0; i < len;) {
_applyListOp(slot, ops[i]);
unchecked {
++i;
}
}
}
function applyListOps(uint256 slot, bytes[] calldata ops) external whenNotPaused onlyListManager(slot) {
_applyListOps(slot, ops);
}
function setMetadataValuesAndApplyListOps(uint256 slot, KeyValue[] calldata records, bytes[] calldata ops)
external
whenNotPaused
onlyListManager(slot)
{
_setMetadataValues(slot, records);
_applyListOps(slot, ops);
}
}
contract EFPListRecords is IEFPListRecords, ListRecords, ENSReverseClaimer {}
文件 3 的 6:ENSReverseClaimer.sol
pragma solidity ^0.8.23;
import {Ownable} from 'lib/openzeppelin-contracts/contracts/access/Ownable.sol';
interface ENS {
function owner(bytes32 node) external view returns (address);
}
interface IReverseRegistrar {
function claim(address owner) external returns (bytes32);
function setName(string memory name) external returns (bytes32);
}
abstract contract ENSReverseClaimer is Ownable {
bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
function claimReverseENS(ENS ens, address claimant) external onlyOwner returns (bytes32) {
return IReverseRegistrar(ens.owner(ADDR_REVERSE_NODE)).claim(claimant);
}
function setReverseENS(ENS ens, string calldata name) external onlyOwner returns (bytes32) {
return IReverseRegistrar(ens.owner(ADDR_REVERSE_NODE)).setName(name);
}
}
文件 4 的 6:IEFPListRecords.sol
pragma solidity ^0.8.23;
interface IEFPListMetadata {
event UpdateListMetadata(uint256 indexed slot, string key, bytes value);
struct KeyValue {
string key;
bytes value;
}
function getMetadataValue(uint256 slot, string calldata key) external view returns (bytes memory);
function getMetadataValues(uint256 slot, string[] calldata keys) external view returns (bytes[] memory);
function setMetadataValue(uint256 slot, string calldata key, bytes calldata value) external;
function setMetadataValues(uint256 slot, KeyValue[] calldata records) external;
function claimListManager(uint256 slot) external;
function claimListManagerForAddress(uint256 slot, address manager) external;
function getListManager(uint256 slot) external view returns (address);
function setListManager(uint256 slot, address manager) external;
function getListUser(uint256 slot) external view returns (address);
function setListUser(uint256 slot, address user) external;
}
interface IEFPListRecords is IEFPListMetadata {
event ListOp(uint256 indexed slot, bytes op);
function getListOpCount(uint256 slot) external view returns (uint256);
function getListOp(uint256 slot, uint256 index) external view returns (bytes memory);
function getListOpsInRange(uint256 slot, uint256 start, uint256 end) external view returns (bytes[] memory);
function getAllListOps(uint256 slot) external view returns (bytes[] memory);
function applyListOp(uint256 slot, bytes calldata op) external;
function applyListOps(uint256 slot, bytes[] calldata ops) external;
function setMetadataValuesAndApplyListOps(uint256 slot, KeyValue[] calldata records, bytes[] calldata ops) external;
}
文件 5 的 6:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 6 的 6:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
{
"compilationTarget": {
"src/EFPListRecords.sol": "EFPListRecords"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ERC721A/=lib/ERC721A/contracts/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/",
":openzeppelin/=lib/openzeppelin-contracts/contracts/"
]
}
[{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"address","name":"manager","type":"address"}],"name":"SlotAlreadyClaimed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"slot","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"op","type":"bytes"}],"name":"ListOp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"slot","type":"uint256"},{"indexed":false,"internalType":"string","name":"key","type":"string"},{"indexed":false,"internalType":"bytes","name":"value","type":"bytes"}],"name":"UpdateListMetadata","type":"event"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"bytes","name":"op","type":"bytes"}],"name":"applyListOp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"bytes[]","name":"ops","type":"bytes[]"}],"name":"applyListOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"}],"name":"claimListManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"address","name":"manager","type":"address"}],"name":"claimListManagerForAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ENS","name":"ens","type":"address"},{"internalType":"address","name":"claimant","type":"address"}],"name":"claimReverseENS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"}],"name":"getAllListOps","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"}],"name":"getListManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getListOp","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"}],"name":"getListOpCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"getListOpsInRange","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"}],"name":"getListUser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"key","type":"string"}],"name":"getMetadataValue","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string[]","name":"keys","type":"string[]"}],"name":"getMetadataValues","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"listOps","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"address","name":"manager","type":"address"}],"name":"setListManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"setListUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"string","name":"key","type":"string"},{"internalType":"bytes","name":"value","type":"bytes"}],"name":"setMetadataValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"components":[{"internalType":"string","name":"key","type":"string"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct IEFPListMetadata.KeyValue[]","name":"records","type":"tuple[]"}],"name":"setMetadataValues","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"components":[{"internalType":"string","name":"key","type":"string"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct IEFPListMetadata.KeyValue[]","name":"records","type":"tuple[]"},{"internalType":"bytes[]","name":"ops","type":"bytes[]"}],"name":"setMetadataValuesAndApplyListOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ENS","name":"ens","type":"address"},{"internalType":"string","name":"name","type":"string"}],"name":"setReverseENS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]