编译器
0.8.17+commit.8df45f5f
文件 1 的 11:AddressUtils.sol
pragma solidity ^0.8.9;
import { UintUtils } from "./UintUtils.sol";
library AddressUtils {
using UintUtils for uint256;
error AddressUtils__InsufficientBalance();
error AddressUtils__NotContract();
error AddressUtils__SendValueFailed();
function toString(address account) internal pure returns (string memory) {
return uint256(uint160(account)).toHexString(20);
}
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable account, uint256 amount) internal {
(bool success, ) = account.call{ value: amount }("");
if (!success) revert AddressUtils__SendValueFailed();
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "AddressUtils: failed low-level call");
}
function functionCall(address target, bytes memory data, string memory error) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, error);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "AddressUtils: failed low-level call with value");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory error) internal returns (bytes memory) {
if (value > address(this).balance) revert AddressUtils__InsufficientBalance();
return _functionCallWithValue(target, data, value, error);
}
function excessivelySafeCall(
address target,
uint256 gasAmount,
uint256 value,
uint16 maxCopy,
bytes memory data
) internal returns (bool success, bytes memory returnData) {
returnData = new bytes(maxCopy);
assembly {
success := call(gasAmount, target, value, add(data, 0x20), mload(data), 0, 0)
let toCopy := returndatasize()
if gt(toCopy, maxCopy) {
toCopy := maxCopy
}
mstore(returnData, toCopy)
returndatacopy(add(returnData, 0x20), 0, toCopy)
}
}
function _functionCallWithValue(address target, bytes memory data, uint256 value, string memory error) private returns (bytes memory) {
if (!isContract(target)) revert AddressUtils__NotContract();
(bool success, bytes memory returnData) = target.call{ value: value }(data);
if (success) {
return returnData;
} else if (returnData.length > 0) {
assembly {
let returnData_size := mload(returnData)
revert(add(32, returnData), returnData_size)
}
} else {
revert(error);
}
}
}
文件 2 的 11:Diamond.sol
pragma solidity ^0.8.9;
import "./base/Diamond/LibDiamondStorage.sol";
import { LibDiamond } from "./base/Diamond/LibDiamond.sol";
import { IDiamondCut } from "./interfaces/IDiamondCut.sol";
contract Diamond {
constructor(address _contractOwner, address _diamondCutFacet) payable {
LibDiamond.setDiamondAddress(address(this));
LibDiamond.setContractOwner(_contractOwner);
IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);
bytes4[] memory functionSelectors = new bytes4[](1);
functionSelectors[0] = IDiamondCut.diamondCut.selector;
cut[0] = IDiamondCut.FacetCut({
facetAddress: _diamondCutFacet,
action: IDiamondCut.FacetCutAction.Add,
functionSelectors: functionSelectors
});
LibDiamond.diamondCut(cut, address(0), "");
}
fallback() external payable {
DiamondStorage storage ds = LibDiamondStorage.layout();
address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;
require(facet != address(0), "Diamond: Function does not exist");
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
receive() external payable {}
}
文件 3 的 11:EnumerableSet.sol
pragma solidity ^0.8.9;
library EnumerableSet {
error EnumerableSet__IndexOutOfBounds();
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
struct Bytes32Set {
Set _inner;
}
struct AddressSet {
Set _inner;
}
struct UintSet {
Set _inner;
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function indexOf(Bytes32Set storage set, bytes32 value) internal view returns (uint256) {
return _indexOf(set._inner, value);
}
function indexOf(AddressSet storage set, address value) internal view returns (uint256) {
return _indexOf(set._inner, bytes32(uint256(uint160(value))));
}
function indexOf(UintSet storage set, uint256 value) internal view returns (uint256) {
return _indexOf(set._inner, bytes32(value));
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function toArray(Bytes32Set storage set) internal view returns (bytes32[] memory) {
return set._inner._values;
}
function toArray(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] storage values = set._inner._values;
address[] storage array;
assembly {
array.slot := values.slot
}
return array;
}
function toArray(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] storage values = set._inner._values;
uint256[] storage array;
assembly {
array.slot := values.slot
}
return array;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
if (index >= set._values.length) revert EnumerableSet__IndexOutOfBounds();
return set._values[index];
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _indexOf(Set storage set, bytes32 value) private view returns (uint256) {
unchecked {
return set._indexes[value] - 1;
}
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _add(Set storage set, bytes32 value) private returns (bool status) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
status = true;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool status) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
unchecked {
bytes32 last = set._values[set._values.length - 1];
set._values[valueIndex - 1] = last;
set._indexes[last] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
status = true;
}
}
}
文件 4 的 11:IDiamondCut.sol
pragma solidity ^0.8.9;
interface IDiamondCut {
enum FacetCutAction {
Add,
Replace,
Remove
}
struct FacetCut {
address facetAddress;
FacetCutAction action;
bytes4[] functionSelectors;
}
function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;
event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
文件 5 的 11:IERC173.sol
pragma solidity ^0.8.9;
interface IERC173 {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function owner() external view returns (address owner_);
function transferOwnership(address _newOwner) external;
}
文件 6 的 11:LibAccessControl.sol
pragma solidity ^0.8.9;
import "./LibAccessControlStorage.sol";
import { IERC173 } from "../../interfaces/IERC173.sol";
import { EnumerableSet } from "../../utils/EnumerableSet.sol";
import { UintUtils } from "../../utils/UintUtils.sol";
import { AddressUtils } from "../../utils/AddressUtils.sol";
library LibAccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
using UintUtils for uint256;
using AddressUtils for address;
error Ownable__NotOwner();
error Ownable__NotTransitiveOwner();
error AccessDenied(bytes32 role, address account);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event RoleAdminChanged(address indexed owner, bytes32 role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(address indexed owner, bytes32 role, address indexed account, address indexed sender);
event RoleRevoked(address indexed owner, bytes32 role, address indexed account, address indexed sender);
bytes32 internal constant DEFAULT_ADMIN_ROLE = 0x00;
function _setOwner(address _newOwner) internal {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
address previousOwner = acls.owner;
acls.owner = _newOwner;
LibAccessControl._grantRole(LibAccessControl.DEFAULT_ADMIN_ROLE, _newOwner);
emit OwnershipTransferred(previousOwner, _newOwner);
}
function _owner() internal view returns (address owner_) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
owner_ = acls.owner;
}
function _transitiveOwner() internal view returns (address owner_) {
owner_ = LibAccessControl._owner();
while (owner_.isContract()) {
try IERC173(owner_).owner() returns (address transitiveOwner) {
owner_ = transitiveOwner;
} catch {
break;
}
}
}
function _enforceIsOwner() internal view {
if (msg.sender != _owner()) {
revert Ownable__NotOwner();
}
}
function _enforceIsTransitiveOwner() internal view {
if (msg.sender != _transitiveOwner()) {
revert Ownable__NotTransitiveOwner();
}
}
function _grantRole(bytes32 _role, address _account) internal {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
if (!_hasRole(_role, _account)) {
acls.roles[acls.owner][_role].members.add(_account);
emit RoleGranted(acls.owner, _role, _account, msg.sender);
}
}
function _revokeRole(bytes32 _role, address _account) internal {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
acls.roles[acls.owner][_role].members.remove(_account);
emit RoleRevoked(acls.owner, _role, _account, msg.sender);
}
function _renounceRole(bytes32 _role) internal {
_revokeRole(_role, msg.sender);
}
function _getRoleMember(bytes32 _role, uint256 _index) internal view returns (address) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].members.at(_index);
}
function _getRoleMemberCount(address, bytes32 _role) internal view returns (uint256) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].members.length();
}
function _hasRole(bytes32 _role, address _account) internal view returns (bool) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].members.contains(_account);
}
function _checkRole(bytes32 _role) internal view {
_checkRole(_role, msg.sender);
}
function _checkRole(bytes32 _role, address _account) internal view {
if (!_hasRole(_role, _account)) {
revert AccessDenied({ role: _role, account: _account });
}
}
function _getRoleAdmin(bytes32 _role) internal view returns (bytes32) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].adminRole;
}
function _setRoleAdmin(bytes32 _role, bytes32 _adminRole) internal {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
bytes32 previousAdminRole = _getRoleAdmin(_role);
acls.roles[acls.owner][_role].adminRole = _adminRole;
emit RoleAdminChanged(acls.owner, _role, previousAdminRole, _adminRole);
}
}
文件 7 的 11:LibAccessControlStorage.sol
pragma solidity ^0.8.9;
import { EnumerableSet } from "../../utils/EnumerableSet.sol";
import "./RoleData.sol";
struct AccessControllStorage {
address owner;
mapping(address => mapping(bytes32 => RoleData)) roles;
}
library LibAccessControlStorage {
bytes32 internal constant STORAGE_SLOT = keccak256("usmart.common.access-control.storage.v1");
function layout() internal pure returns (AccessControllStorage storage acls_) {
bytes32 position = STORAGE_SLOT;
assembly {
acls_.slot := position
}
}
}
文件 8 的 11:LibDiamond.sol
pragma solidity ^0.8.9;
import "./LibDiamondStorage.sol";
import { IDiamondCut } from "../../interfaces/IDiamondCut.sol";
import { LibAccessControl } from "../AccessControl/LibAccessControl.sol";
error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);
library LibDiamond {
event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
function setDiamondAddress(address _diamondAddress) internal {
DiamondStorage storage ds = LibDiamondStorage.layout();
require(ds.diamondAddress == address(0), "Already initialized!");
ds.diamondAddress = _diamondAddress;
}
function getDiamondAddress() internal view returns (address) {
DiamondStorage storage ds = LibDiamondStorage.layout();
return ds.diamondAddress;
}
function setContractOwner(address _newOwner) internal {
LibAccessControl._setOwner(_newOwner);
}
function enforceIsContractOwner() internal view {
LibAccessControl._enforceIsOwner();
}
function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata) internal {
for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
if (action == IDiamondCut.FacetCutAction.Add) {
addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} else if (action == IDiamondCut.FacetCutAction.Replace) {
replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} else if (action == IDiamondCut.FacetCutAction.Remove) {
removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} else {
revert("LibDiamondCut: Incorrect FacetCutAction");
}
}
emit DiamondCut(_diamondCut, _init, _calldata);
initializeDiamondCut(_init, _calldata);
}
function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
DiamondStorage storage ds = LibDiamondStorage.layout();
require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
if (selectorPosition == 0) {
addFacet(ds, _facetAddress);
}
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
addFunction(ds, selector, selectorPosition, _facetAddress);
selectorPosition++;
}
}
function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
DiamondStorage storage ds = LibDiamondStorage.layout();
require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
if (selectorPosition == 0) {
addFacet(ds, _facetAddress);
}
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
removeFunction(ds, oldFacetAddress, selector);
addFunction(ds, selector, selectorPosition, _facetAddress);
selectorPosition++;
}
}
function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
DiamondStorage storage ds = LibDiamondStorage.layout();
require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
removeFunction(ds, oldFacetAddress, selector);
}
}
function addFacet(DiamondStorage storage ds, address _facetAddress) internal {
enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
ds.facetAddresses.push(_facetAddress);
}
function addFunction(DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress) internal {
ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
}
function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {
require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
if (selectorPosition != lastSelectorPosition) {
bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
}
ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
delete ds.selectorToFacetAndPosition[_selector];
if (lastSelectorPosition == 0) {
uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
if (facetAddressPosition != lastFacetAddressPosition) {
address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
}
ds.facetAddresses.pop();
delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
}
}
function initializeDiamondCut(address _init, bytes memory _calldata) internal {
if (_init == address(0)) {
return;
}
enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
(bool success, bytes memory error) = _init.delegatecall(_calldata);
if (!success) {
if (error.length > 0) {
assembly {
let returndata_size := mload(error)
revert(add(32, error), returndata_size)
}
} else {
revert InitializationFunctionReverted(_init, _calldata);
}
}
}
function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
uint256 contractSize;
assembly {
contractSize := extcodesize(_contract)
}
require(contractSize > 0, _errorMessage);
}
}
文件 9 的 11:LibDiamondStorage.sol
pragma solidity ^0.8.9;
import { EnumerableSet } from "../../utils/EnumerableSet.sol";
struct FacetAddressAndPosition {
address facetAddress;
uint96 functionSelectorPosition;
}
struct FacetFunctionSelectors {
bytes4[] functionSelectors;
uint256 facetAddressPosition;
}
struct DiamondStorage {
address diamondAddress;
mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
address[] facetAddresses;
mapping(bytes4 => bool) supportedInterfaces;
bool paused;
}
library LibDiamondStorage {
bytes32 internal constant STORAGE_SLOT = keccak256("usmart.contracts.diamond.storage.v1");
function layout() internal pure returns (DiamondStorage storage layout_) {
bytes32 position = STORAGE_SLOT;
assembly {
layout_.slot := position
}
}
}
文件 10 的 11:RoleData.sol
pragma solidity ^0.8.9;
import { EnumerableSet } from "../../utils/EnumerableSet.sol";
struct RoleData {
bytes32 adminRole;
EnumerableSet.AddressSet members;
}
文件 11 的 11:UintUtils.sol
pragma solidity ^0.8.9;
library UintUtils {
error UintUtils__InsufficientHexLength();
bytes16 private constant HEX_SYMBOLS = "0123456789abcdef";
function add(uint256 a, int256 b) internal pure returns (uint256) {
return b < 0 ? sub(a, -b) : a + uint256(b);
}
function sub(uint256 a, int256 b) internal pure returns (uint256) {
return b < 0 ? add(a, -b) : a - uint256(b);
}
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 length = 0;
for (uint256 temp = value; temp != 0; temp >>= 8) {
unchecked {
length++;
}
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
unchecked {
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
}
if (value != 0) revert UintUtils__InsufficientHexLength();
return string(buffer);
}
}
{
"compilationTarget": {
"contracts/Diamond.sol": "Diamond"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_contractOwner","type":"address"},{"internalType":"address","name":"_diamondCutFacet","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_initializationContractAddress","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"InitializationFunctionReverted","type":"error"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]