Address Contract Verified
Address
0xEEb00E283259d5E1930f27c62552A6a6BE510348
Balance
0 ETH
Nonce
1
Code Size
9584 bytes
Creator
0x4C05aDEf...7Fd9 at tx 0xbf357a39...6ea076
Proxy
EIP-1967 Proxy Implementation: 0x36EaE2bD...3b1f
Indexed Transactions
0
Contract Bytecode
9584 bytes
0x60806040523661000b57005b600061001561014a565b9050600081600101600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610124576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161011b906119be565b60405180910390fd5b3660008037600080366000845af43d6000803e8060008114610145573d6000f35b3d6000fd5b6000807ff72346055b4d7224c7ec19860d22963ca622fbb313761bfba507c1a3aeedf37290508091505090565b600061018161014a565b9050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610216576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161020d90611a2a565b60405180910390fd5b818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61026681610498565b50565b60005b835181101561044d57600084828151811061028a57610289611a4a565b5b6020026020010151602001519050600060028111156102ac576102ab611a79565b5b8160028111156102bf576102be611a79565b5b0361030f5761030a8583815181106102da576102d9611a4a565b5b6020026020010151600001518684815181106102f9576102f8611a4a565b5b602002602001015160400151610755565b610439565b6001600281111561032357610322611a79565b5b81600281111561033657610335611a79565b5b036103865761038185838151811061035157610350611a4a565b5b6020026020010151600001518684815181106103705761036f611a4a565b5b6020026020010151604001516109cc565b610438565b60028081111561039957610398611a79565b5b8160028111156103ac576103ab611a79565b5b036103fc576103f78583815181106103c7576103c6611a4a565b5b6020026020010151600001518684815181106103e6576103e5611a4a565b5b602002602001015160400151610c4d565b610437565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042e90611b1a565b60405180910390fd5b5b5b50808061044590611b73565b91505061026c565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161048193929190611edf565b60405180910390a16104938282610dd8565b505050565b60006104a261057c565b905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061051d6000801b846105a9565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6000807f746c6723185dc95a8925081faed89cbd4670299390e2ebfb0b9c3e755e204ef490508091505090565b60006105b361057c565b90506105bf8383610efa565b6106f05761064e828260010160008460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008681526020019081526020016000206001016106f590919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fc1ddb807f72f9e732ef6f32805c68a3b77ca377c0e141fe3bcaf19fe667f3534866040516106e79190611f3d565b60405180910390a45b505050565b600061071d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610f9b565b905092915050565b600061074d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611002565b905092915050565b6000815111610799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079090611fca565b60405180910390fd5b60006107a361014a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080b9061205c565b60405180910390fd5b60008160020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff1603610881576108808285611025565b5b60005b83518110156109c55760008482815181106108a2576108a1611a4a565b5b602002602001015190506000846001016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610996576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098d906120ee565b60405180910390fd5b6109a28583868a611100565b83806109ad90612126565b945050505080806109bd90611b73565b915050610884565b5050505050565b6000815111610a10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0790611fca565b60405180910390fd5b6000610a1a61014a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a829061205c565b60405180910390fd5b60008160020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff1603610af857610af78285611025565b5b60005b8351811015610c46576000848281518110610b1957610b18611a4a565b5b602002602001015190506000846001016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c03906121cc565b60405180910390fd5b610c178582846112ad565b610c238583868a611100565b8380610c2e90612126565b94505050508080610c3e90611b73565b915050610afb565b5050505050565b6000815111610c91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8890611fca565b60405180910390fd5b6000610c9b61014a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610d0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d039061225e565b60405180910390fd5b60005b8251811015610dd2576000838281518110610d2d57610d2c611a4a565b5b602002602001015190506000836001016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610dbd8482846112ad565b50508080610dca90611b73565b915050610d0f565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160315610ef657610e2f826040518060600160405280602881526020016124ef6028913961190f565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610e5791906122ba565b600060405180830381855af49150503d8060008114610e92576040519150601f19603f3d011682016040523d82523d6000602084013e610e97565b606091505b509150915081610ef357600081511115610eb45780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610eea9291906122d1565b60405180910390fd5b50505b5050565b600080610f0561057c565b9050610f92838260010160008460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600087815260200190815260200160002060010161072590919063ffffffff16565b91505092915050565b6000610fa78383611002565b610ffc5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b611047816040518060600160405280602481526020016125176024913961190f565b81600301805490508260020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600301819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846001016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360020160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846001016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361131c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131390612373565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361138a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138190612405565b60405180910390fd5b6000836001016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560020160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805490506114619190612425565b90508082146115f55760008560020160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106114c2576114c1611a4a565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660020160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001848154811061153e5761153d611a4a565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866001016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180548061164957611648612459565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846001016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff0219169055505060008103611908576000600186600301805490506117339190612425565b905060008660020160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905081811461187457600087600301838154811061179d5761179c611a4a565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808860030183815481106117e1576117e0611a4a565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b8660030180548061188857611887612459565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660020160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b905060008111829061195b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195291906124cc565b60405180910390fd5b50505050565b600082825260208201905092915050565b7f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f74206578697374600082015250565b60006119a8602083611961565b91506119b382611972565b602082019050919050565b600060208201905081810360008301526119d78161199b565b9050919050565b7f416c726561647920696e697469616c697a656421000000000000000000000000600082015250565b6000611a14601483611961565b9150611a1f826119de565b602082019050919050565b60006020820190508181036000830152611a4381611a07565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560008201527f74416374696f6e00000000000000000000000000000000000000000000000000602082015250565b6000611b04602783611961565b9150611b0f82611aa8565b604082019050919050565b60006020820190508181036000830152611b3381611af7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000611b7e82611b69565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611bb057611baf611b3a565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611c1282611be7565b9050919050565b611c2281611c07565b82525050565b60038110611c3957611c38611a79565b5b50565b6000819050611c4a82611c28565b919050565b6000611c5a82611c3c565b9050919050565b611c6a81611c4f565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611cd181611c9c565b82525050565b6000611ce38383611cc8565b60208301905092915050565b6000602082019050919050565b6000611d0782611c70565b611d118185611c7b565b9350611d1c83611c8c565b8060005b83811015611d4d578151611d348882611cd7565b9750611d3f83611cef565b925050600181019050611d20565b5085935050505092915050565b6000606083016000830151611d726000860182611c19565b506020830151611d856020860182611c61565b5060408301518482036040860152611d9d8282611cfc565b9150508091505092915050565b6000611db68383611d5a565b905092915050565b6000602082019050919050565b6000611dd682611bbb565b611de08185611bc6565b935083602082028501611df285611bd7565b8060005b85811015611e2e5784840389528151611e0f8582611daa565b9450611e1a83611dbe565b925060208a01995050600181019050611df6565b50829750879550505050505092915050565b611e4981611c07565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611e89578082015181840152602081019050611e6e565b60008484015250505050565b6000601f19601f8301169050919050565b6000611eb182611e4f565b611ebb8185611e5a565b9350611ecb818560208601611e6b565b611ed481611e95565b840191505092915050565b60006060820190508181036000830152611ef98186611dcb565b9050611f086020830185611e40565b8181036040830152611f1a8184611ea6565b9050949350505050565b6000819050919050565b611f3781611f24565b82525050565b6000602082019050611f526000830184611f2e565b92915050565b7f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660008201527f6163657420746f20637574000000000000000000000000000000000000000000602082015250565b6000611fb4602b83611961565b9150611fbf82611f58565b604082019050919050565b60006020820190508181036000830152611fe381611fa7565b9050919050565b7f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260008201527f6520616464726573732830290000000000000000000000000000000000000000602082015250565b6000612046602c83611961565b915061205182611fea565b604082019050919050565b6000602082019050818103600083015261207581612039565b9050919050565b7f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60008201527f6e207468617420616c7265616479206578697374730000000000000000000000602082015250565b60006120d8603583611961565b91506120e38261207c565b604082019050919050565b60006020820190508181036000830152612107816120cb565b9050919050565b60006bffffffffffffffffffffffff82169050919050565b60006121318261210e565b91506bffffffffffffffffffffffff820361214f5761214e611b3a565b5b600182019050919050565b7f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60008201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000602082015250565b60006121b6603883611961565b91506121c18261215a565b604082019050919050565b600060208201905081810360008301526121e5816121a9565b9050919050565b7f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260008201527f657373206d757374206265206164647265737328302900000000000000000000602082015250565b6000612248603683611961565b9150612253826121ec565b604082019050919050565b600060208201905081810360008301526122778161223b565b9050919050565b600081905092915050565b600061229482611e4f565b61229e818561227e565b93506122ae818560208601611e6b565b80840191505092915050565b60006122c68284612289565b915081905092915050565b60006040820190506122e66000830185611e40565b81810360208301526122f88184611ea6565b90509392505050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360008201527f74696f6e207468617420646f65736e2774206578697374000000000000000000602082015250565b600061235d603783611961565b915061236882612301565b604082019050919050565b6000602082019050818103600083015261238c81612350565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560008201527f7461626c652066756e6374696f6e000000000000000000000000000000000000602082015250565b60006123ef602e83611961565b91506123fa82612393565b604082019050919050565b6000602082019050818103600083015261241e816123e2565b9050919050565b600061243082611b69565b915061243b83611b69565b925082820390508181111561245357612452611b3a565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081519050919050565b600061249e82612488565b6124a88185611961565b93506124b8818560208601611e6b565b6124c181611e95565b840191505092915050565b600060208201905081810360008301526124e68184612493565b90509291505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122070fbd06feff1b7a70998a1d6e378d8024f260233de4e3d33541526982e33ada164736f6c63430008110033
Verified Source Code Full Match
Compiler: v0.8.17+commit.8df45f5f
EVM: london
Optimization: No
Diamond.sol 59 lines
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 * * Implementation of a diamond. /******************************************************************************/ 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); // Add the diamondCut external function from the diamondCutFacet 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), ""); } // Find facet for function that is called and execute the // function if a facet is found and return any value. fallback() external payable { DiamondStorage storage ds = LibDiamondStorage.layout(); // get facet from function selector address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress; require(facet != address(0), "Diamond: Function does not exist"); // Execute external function from facet using delegatecall and return any value. assembly { // copy function selector and any arguments calldatacopy(0, 0, calldatasize()) // execute function call using the facet let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) // get any return value returndatacopy(0, 0, returndatasize()) // return any return value or error back to the caller switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } receive() external payable {} }
UintUtils.sol 80 lines
// SPDX-License-Identifier: MIT
/**
* Copyright (C) 2024 uSmart
*/
pragma solidity ^0.8.9;
/**
* @title utility functions for uint256 operations
* @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
*/
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);
}
}
IERC173.sol 21 lines
// SPDX-License-Identifier: MIT
/**
* Copyright (C) 2024 uSmart
*/
pragma solidity ^0.8.9;
/// @title ERC-173 Contract Ownership Standard
/// Note: the ERC-165 identifier for this interface is 0x7f5828d0
interface IERC173 {
/// @dev This emits when ownership of a contract changes.
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/// @notice Get the address of the owner
/// @return owner_ The address of the owner.
function owner() external view returns (address owner_);
/// @notice Set the address of the new owner of the contract
/// @dev Set _newOwner to address(0) to renounce any ownership.
/// @param _newOwner The address of the new owner of the contract
function transferOwnership(address _newOwner) external;
}
AddressUtils.sol 105 lines
// SPDX-License-Identifier: MIT
/**
* Copyright (C) 2024 uSmart
*/
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);
}
/**
* @notice execute arbitrary external call with limited gas usage and amount of copied return data
* @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License)
* @param target recipient of call
* @param gasAmount gas allowance for call
* @param value native token value to include in call
* @param maxCopy maximum number of bytes to copy from return data
* @param data encoded call data
* @return success whether call is successful
* @return returnData copied return data
*/
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 {
// execute external call via assembly to avoid automatic copying of return data
success := call(gasAmount, target, value, add(data, 0x20), mload(data), 0, 0)
// determine whether to limit amount of data to copy
let toCopy := returndatasize()
if gt(toCopy, maxCopy) {
toCopy := maxCopy
}
// store the length of the copied bytes
mstore(returnData, toCopy)
// copy the bytes from returndata[0: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);
}
}
}
EnumerableSet.sol 177 lines
// SPDX-License-Identifier: MIT
/**
* Copyright (C) 2024 uSmart
*/
pragma solidity ^0.8.9;
/**
* @title Set implementation with enumeration functions
* @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)
*/
library EnumerableSet {
error EnumerableSet__IndexOutOfBounds();
struct Set {
bytes32[] _values;
// 1-indexed to allow 0 to signify nonexistence
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];
// move last value to now-vacant index
set._values[valueIndex - 1] = last;
set._indexes[last] = valueIndex;
}
// clear last index
set._values.pop();
delete set._indexes[value];
status = true;
}
}
}
IDiamondCut.sol 32 lines
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface IDiamondCut { enum FacetCutAction { Add, Replace, Remove } // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
LibDiamond.sol 178 lines
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ import "./LibDiamondStorage.sol"; import { IDiamondCut } from "../../interfaces/IDiamondCut.sol"; import { LibAccessControl } from "../AccessControl/LibAccessControl.sol"; // Remember to add the loupe functions from DiamondLoupeFacet to the diamond. // The loupe functions are required by the EIP2535 Diamonds standard 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(); } // Internal function version of diamondCut 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); // add new facet address if it does not exist 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); // add new facet address if it does not exist 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(); // if function does not exist then do nothing and return 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"); // an immutable function is a function defined directly in a diamond require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function"); // replace selector with last selector, then delete last selector uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition; uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1; // if not the same then replace _selector with lastSelector if (selectorPosition != lastSelectorPosition) { bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition]; ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector; ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition); } // delete the last selector ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop(); delete ds.selectorToFacetAndPosition[_selector]; // if no more selectors for facet address then delete the facet address if (lastSelectorPosition == 0) { // replace facet address with last facet address and delete last facet address 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) { // bubble up error /// @solidity memory-safe-assembly 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); } }
RoleData.sol 12 lines
// SPDX-License-Identifier: MIT
/**
* Copyright (C) 2024 uSmart
*/
pragma solidity ^0.8.9;
import { EnumerableSet } from "../../utils/EnumerableSet.sol";
struct RoleData {
bytes32 adminRole;
EnumerableSet.AddressSet members;
}
LibDiamondStorage.sol 41 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import { EnumerableSet } from "../../utils/EnumerableSet.sol";
struct FacetAddressAndPosition {
address facetAddress;
uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
}
struct FacetFunctionSelectors {
bytes4[] functionSelectors;
uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
}
struct DiamondStorage {
address diamondAddress;
// maps function selector to the facet address and
// the position of the selector in the facetFunctionSelectors.selectors array
mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
// maps facet addresses to function selectors
mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
// facet addresses
address[] facetAddresses;
// Used to query if a contract implements an interface.
// Used to implement ERC-165.
mapping(bytes4 => bool) supportedInterfaces;
//the whole diamond is paused or not
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
}
}
}
LibAccessControl.sol 180 lines
// SPDX-License-Identifier: MIT
/**
* Copyright (C) 2024 uSmart
*/
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;
//Init DEFAULT_ADMIN_ROLE to _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 {
//require(msg.sender == _owner(), "Not owner!");
if (msg.sender != _owner()) {
revert Ownable__NotOwner();
}
}
function _enforceIsTransitiveOwner() internal view {
//require(msg.sender == _transitiveOwner(), "Not transitive owner!");
if (msg.sender != _transitiveOwner()) {
revert Ownable__NotTransitiveOwner();
}
}
/**
* @notice assign role to given account
* @param _role role to assign
* @param _account recipient of role assignment
*/
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);
}
}
/**
* @notice unassign role from given account
* @param _role role to unassign
* @param _account account to revokeAccessControlStorage
*/
function _revokeRole(bytes32 _role, address _account) internal {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
// require(_role != LibAccessControl.DEFAULT_ADMIN_ROLE && _account != acls.owner);
acls.roles[acls.owner][_role].members.remove(_account);
emit RoleRevoked(acls.owner, _role, _account, msg.sender);
}
/**
* @notice relinquish role
* @param _role role to relinquish
*/
function _renounceRole(bytes32 _role) internal {
_revokeRole(_role, msg.sender);
}
/**
* @notice Query one of the accounts that have role of the project
* @dev WARNING: When using _getProjectRoleMember and _getProjectRoleMemberCount, make sure you perform all queries on the same block.
* @param _role role to query
* @param _index index of role member
*/
function _getRoleMember(bytes32 _role, uint256 _index) internal view returns (address) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].members.at(_index);
}
/**
* @notice Query the number of accounts that have role.
* @dev WARNING: When using _getRoleMember and _getRoleMemberCount, make sure you perform all queries on the same block.
* @param _role role to query
*/
function _getRoleMemberCount(address, bytes32 _role) internal view returns (uint256) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].members.length();
}
/**
* @notice query whether role is assigned to account
* @param _role role to query
* @param _account account to query
* @return bool whether role is assigned to account
*/
function _hasRole(bytes32 _role, address _account) internal view returns (bool) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].members.contains(_account);
}
/**
* @notice revert if sender does not have given role
* @param _role role to query
*/
function _checkRole(bytes32 _role) internal view {
_checkRole(_role, msg.sender);
}
/**
* @notice revert if given account does not have given role
* @param _role role to query
* @param _account to query
*/
function _checkRole(bytes32 _role, address _account) internal view {
if (!_hasRole(_role, _account)) {
revert AccessDenied({ role: _role, account: _account });
}
}
/**
* @notice query admin role for given role
* @param _role role to query
* @return admin role
*/
function _getRoleAdmin(bytes32 _role) internal view returns (bytes32) {
AccessControllStorage storage acls = LibAccessControlStorage.layout();
return acls.roles[acls.owner][_role].adminRole;
}
/**
* @notice set role as admin role
* @param _role role to set
* @param _adminRole admin role to set
*/
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);
}
}
LibAccessControlStorage.sol 25 lines
// SPDX-License-Identifier: MIT
/**
* Copyright (C) 2024 uSmart
*/
pragma solidity ^0.8.9;
import { EnumerableSet } from "../../utils/EnumerableSet.sol";
import "./RoleData.sol";
struct AccessControllStorage {
//owner => role => adminRole, members mapping
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
}
}
}
Token Balances (1)
View Transfers →Recent Transactions
No transactions found for this address