This contract's source code is verified! Compiler
0.8.4+commit.c7e474f2
File 1 of 21: AddressUtils.sol
pragma solidity ^0.8.0;
library AddressUtils {
function toString (address account ) internal pure returns (string memory ) {
bytes32 value = bytes32 (uint256 (uint160 (account)));
bytes memory alphabet = '0123456789abcdef' ;
bytes memory chars = new bytes (42 );
chars[0 ] = '0' ;
chars[1 ] = 'x' ;
for (uint256 i = 0 ; i < 20 ; i+ + ) {
chars[2 + i * 2 ] = alphabet[uint8 (value[i + 12 ] > > 4 )];
chars[3 + i * 2 ] = alphabet[uint8 (value[i + 12 ] & 0x0f )];
}
return string (chars);
}
function isContract (address account ) internal view returns (bool ) {
uint size;
assembly { size := extcodesize (account) }
return size > 0 ;
}
function sendValue (address payable account, uint amount ) internal {
(bool success, ) = account.call { value : amount }('' );
require (success, 'AddressUtils: failed to send value' );
}
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, uint value ) internal returns (bytes memory ) {
return functionCallWithValue(target, data, value, 'AddressUtils: failed low-level call with value' );
}
function functionCallWithValue (address target, bytes memory data, uint value, string memory error ) internal returns (bytes memory ) {
require (address (this ).balance > = value, 'AddressUtils: insufficient balance for call' );
return _functionCallWithValue(target, data, value, error ) ;
}
function _functionCallWithValue (address target, bytes memory data, uint value, string memory error ) private returns (bytes memory ) {
require (isContract(target), 'AddressUtils: function call to non-contract' );
(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 ) ;
}
}
}
File 2 of 21: Diamond.sol
pragma solidity ^0.8.0;
import {SafeOwnable , OwnableStorage , Ownable } from '../../access/SafeOwnable.sol' ;
import {IERC173 } from '../../access/IERC173.sol' ;
import {ERC165 , IERC165 , ERC165Storage } from '../../introspection/ERC165.sol' ;
import {DiamondBase , DiamondBaseStorage } from './DiamondBase.sol' ;
import {DiamondCuttable , IDiamondCuttable } from './DiamondCuttable.sol' ;
import {DiamondLoupe , IDiamondLoupe } from './DiamondLoupe.sol' ;
abstract contract Diamond is DiamondBase , DiamondCuttable , DiamondLoupe , SafeOwnable , ERC165 {
using DiamondBaseStorage for DiamondBaseStorage .Layout ;
using ERC165Storage for ERC165Storage .Layout ;
using OwnableStorage for OwnableStorage .Layout ;
constructor ( ) {
ERC165Storage.Layout storage erc165 = ERC165Storage.layout();
bytes4 [] memory selectors = new bytes4 [](12 );
selectors[0 ] = IDiamondCuttable.diamondCut.selector ;
erc165.setSupportedInterface(type (IDiamondCuttable).interfaceId , true );
selectors[1 ] = IDiamondLoupe.facets.selector ;
selectors[2 ] = IDiamondLoupe.facetFunctionSelectors.selector ;
selectors[3 ] = IDiamondLoupe.facetAddresses.selector ;
selectors[4 ] = IDiamondLoupe.facetAddress.selector ;
erc165.setSupportedInterface(type (IDiamondLoupe).interfaceId , true );
selectors[5 ] = IERC165.supportsInterface.selector ;
erc165.setSupportedInterface(type (IERC165).interfaceId , true );
selectors[6 ] = Ownable.owner.selector ;
selectors[7 ] = SafeOwnable.nomineeOwner.selector ;
selectors[8 ] = SafeOwnable.transferOwnership.selector ;
selectors[9 ] = SafeOwnable.acceptOwnership.selector ;
erc165.setSupportedInterface(type (IERC173).interfaceId , true );
selectors[10 ] = Diamond.getFallbackAddress.selector ;
selectors[11 ] = Diamond.setFallbackAddress.selector ;
FacetCut[] memory facetCuts = new FacetCut[](1 );
facetCuts[0 ] = FacetCut({
target: address (this ),
action: IDiamondCuttable.FacetCutAction.ADD,
selectors: selectors
});
DiamondBaseStorage.layout().diamondCut(facetCuts, address (0 ), '' );
OwnableStorage.layout().setOwner(msg .sender );
}
receive ( ) external payable {}
function getFallbackAddress ( ) external view returns (address ) {
return DiamondBaseStorage.layout().fallbackAddress;
}
function setFallbackAddress (
address fallbackAddress
) external onlyOwner {
DiamondBaseStorage.layout().fallbackAddress = fallbackAddress;
}
}
File 3 of 21: DiamondBase.sol
pragma solidity ^0.8.0;
import {Proxy } from '../Proxy.sol' ;
import {DiamondBaseStorage } from './DiamondBaseStorage.sol' ;
import {IDiamondLoupe } from './IDiamondLoupe.sol' ;
import {IDiamondCuttable } from './IDiamondCuttable.sol' ;
abstract contract DiamondBase is Proxy {
function _getImplementation ( ) override internal view returns (address ) {
DiamondBaseStorage.Layout storage l;
bytes32 slot = DiamondBaseStorage.STORAGE_SLOT;
assembly { l.slot := slot }
address implementation = address (bytes20 (l.facets[msg .sig ]));
if (implementation = = address (0 )) {
implementation = l.fallbackAddress;
require (
implementation ! = address (0 ),
'DiamondBase: no facet found for function signature'
);
}
return implementation;
}
}
File 4 of 21: DiamondBaseStorage.sol
pragma solidity ^0.8.0;
import {AddressUtils } from '../../utils/AddressUtils.sol' ;
import {IDiamondCuttable } from './IDiamondCuttable.sol' ;
library DiamondBaseStorage {
using AddressUtils for address ;
using DiamondBaseStorage for DiamondBaseStorage .Layout ;
struct Layout {
mapping (bytes4 = > bytes32 ) facets;
uint16 selectorCount;
mapping (uint256 = > bytes32 ) selectorSlots;
address fallbackAddress;
}
bytes32 constant CLEAR_ADDRESS_MASK = bytes32 (uint256 (0xffffffffffffffffffffffff ));
bytes32 constant CLEAR_SELECTOR_MASK = bytes32 (uint256 (0xffffffff < < 224 ));
bytes32 internal constant STORAGE_SLOT = keccak256 (
'solidstate.contracts.storage.DiamondBase'
);
event DiamondCut (IDiamondCuttable.FacetCut[] facetCuts, address target, bytes data ) ;
function layout ( ) internal pure returns (Layout storage l ) {
bytes32 slot = STORAGE_SLOT;
assembly { l.slot := slot }
}
function diamondCut (
Layout storage l,
IDiamondCuttable.FacetCut[] memory facetCuts,
address target,
bytes memory data
) internal {
unchecked {
uint256 originalSelectorCount = l.selectorCount;
uint256 selectorCount = originalSelectorCount;
bytes32 selectorSlot;
if (selectorCount & 7 > 0 ) {
selectorSlot = l.selectorSlots[selectorCount > > 3 ];
}
for (uint256 i; i < facetCuts.length ; i+ + ) {
IDiamondCuttable.FacetCut memory facetCut = facetCuts[i];
IDiamondCuttable.FacetCutAction action = facetCut.action;
require (
facetCut.selectors.length > 0 ,
'DiamondBase: no selectors specified'
);
if (action = = IDiamondCuttable.FacetCutAction.ADD) {
(selectorCount, selectorSlot) = l.addFacetSelectors(
selectorCount,
selectorSlot,
facetCut
);
} else if (action = = IDiamondCuttable.FacetCutAction.REMOVE) {
(selectorCount, selectorSlot) = l.removeFacetSelectors(
selectorCount,
selectorSlot,
facetCut
);
} else if (action = = IDiamondCuttable.FacetCutAction.REPLACE) {
l.replaceFacetSelectors(facetCut);
}
}
if (selectorCount ! = originalSelectorCount) {
l.selectorCount = uint16 (selectorCount);
}
if (selectorCount & 7 > 0 ) {
l.selectorSlots[selectorCount > > 3 ] = selectorSlot;
}
emit DiamondCut(facetCuts, target, data);
initialize(target, data);
}
}
function addFacetSelectors (
Layout storage l,
uint256 selectorCount,
bytes32 selectorSlot,
IDiamondCuttable.FacetCut memory facetCut
) internal returns (uint256 , bytes32 ) {
unchecked {
require (
facetCut.target = = address (this ) | | facetCut.target.isContract(),
'DiamondBase: ADD target has no code'
);
for (uint256 i; i < facetCut.selectors.length ; i+ + ) {
bytes4 selector = facetCut.selectors[i];
bytes32 oldFacet = l.facets[selector];
require (
address (bytes20 (oldFacet)) = = address (0 ),
'DiamondBase: selector already added'
);
l.facets[selector] = bytes20 (facetCut.target) | bytes32 (selectorCount);
uint256 selectorInSlotPosition = (selectorCount & 7 ) < < 5 ;
selectorSlot = (
selectorSlot & ~ (CLEAR_SELECTOR_MASK > > selectorInSlotPosition)
) | (bytes32 (selector) > > selectorInSlotPosition);
if (selectorInSlotPosition = = 224 ) {
l.selectorSlots[selectorCount > > 3 ] = selectorSlot;
selectorSlot = 0 ;
}
selectorCount+ + ;
}
return (selectorCount, selectorSlot);
}
}
function removeFacetSelectors (
Layout storage l,
uint256 selectorCount,
bytes32 selectorSlot,
IDiamondCuttable.FacetCut memory facetCut
) internal returns (uint256 , bytes32 ) {
unchecked {
require (
facetCut.target = = address (0 ),
'DiamondBase: REMOVE target must be zero address'
);
uint256 selectorSlotCount = selectorCount > > 3 ;
uint256 selectorInSlotIndex = selectorCount & 7 ;
for (uint256 i; i < facetCut.selectors.length ; i+ + ) {
bytes4 selector = facetCut.selectors[i];
bytes32 oldFacet = l.facets[selector];
require (
address (bytes20 (oldFacet)) ! = address (0 ),
'DiamondBase: selector not found'
);
require (
address (bytes20 (oldFacet)) ! = address (this ),
'DiamondBase: selector is immutable'
);
if (selectorSlot = = 0 ) {
selectorSlotCount- - ;
selectorSlot = l.selectorSlots[selectorSlotCount];
selectorInSlotIndex = 7 ;
} else {
selectorInSlotIndex- - ;
}
bytes4 lastSelector;
uint256 oldSelectorsSlotCount;
uint256 oldSelectorInSlotPosition;
{
lastSelector = bytes4 (selectorSlot < < (selectorInSlotIndex < < 5 ));
if (lastSelector ! = selector) {
l.facets[lastSelector] = (
oldFacet & CLEAR_ADDRESS_MASK
) | bytes20 (l.facets[lastSelector]);
}
delete l.facets[selector];
uint256 oldSelectorCount = uint16 (uint256 (oldFacet));
oldSelectorsSlotCount = oldSelectorCount > > 3 ;
oldSelectorInSlotPosition = (oldSelectorCount & 7 ) < < 5 ;
}
if (oldSelectorsSlotCount ! = selectorSlotCount) {
bytes32 oldSelectorSlot = l.selectorSlots[oldSelectorsSlotCount];
oldSelectorSlot = (
oldSelectorSlot & ~ (CLEAR_SELECTOR_MASK > > oldSelectorInSlotPosition)
) | (bytes32 (lastSelector) > > oldSelectorInSlotPosition);
l.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;
} else {
selectorSlot = (
selectorSlot & ~ (CLEAR_SELECTOR_MASK > > oldSelectorInSlotPosition)
) | (bytes32 (lastSelector) > > oldSelectorInSlotPosition);
}
if (selectorInSlotIndex = = 0 ) {
delete l.selectorSlots[selectorSlotCount];
selectorSlot = 0 ;
}
}
selectorCount = (selectorSlotCount < < 3 ) | selectorInSlotIndex;
return (selectorCount, selectorSlot);
}
}
function replaceFacetSelectors (
Layout storage l,
IDiamondCuttable.FacetCut memory facetCut
) internal {
unchecked {
require (
facetCut.target.isContract(),
'DiamondBase: REPLACE target has no code'
);
for (uint256 i; i < facetCut.selectors.length ; i+ + ) {
bytes4 selector = facetCut.selectors[i];
bytes32 oldFacet = l.facets[selector];
address oldFacetAddress = address (bytes20 (oldFacet));
require (
oldFacetAddress ! = address (0 ),
'DiamondBase: selector not found'
);
require (
oldFacetAddress ! = address (this ),
'DiamondBase: selector is immutable'
);
require (
oldFacetAddress ! = facetCut.target,
'DiamondBase: REPLACE target is identical'
);
l.facets[selector] = (oldFacet & CLEAR_ADDRESS_MASK) | bytes20 (facetCut.target);
}
}
}
function initialize (
address target,
bytes memory data
) private {
require (
(target = = address (0 )) = = (data.length = = 0 ),
'DiamondBase: invalid initialization parameters'
);
if (target ! = address (0 )) {
if (target ! = address (this )) {
require (
target.isContract(),
'DiamondBase: initialization target has no code'
);
}
(bool success, ) = target.delegatecall (data);
if (! success) {
assembly {
returndatacopy (0 , 0 , returndatasize ())
revert (0 , returndatasize ())
}
}
}
}
}
File 5 of 21: DiamondCuttable.sol
pragma solidity ^0.8.0;
import {OwnableInternal } from '../../access/OwnableInternal.sol' ;
import {IDiamondCuttable } from './IDiamondCuttable.sol' ;
import {DiamondBaseStorage } from './DiamondBaseStorage.sol' ;
abstract contract DiamondCuttable is IDiamondCuttable , OwnableInternal {
using DiamondBaseStorage for DiamondBaseStorage .Layout ;
function diamondCut (
FacetCut[] calldata facetCuts,
address target,
bytes calldata data
) external override onlyOwner {
DiamondBaseStorage.layout().diamondCut(facetCuts, target, data);
}
}
File 6 of 21: DiamondLoupe.sol
pragma solidity ^0.8.0;
import {DiamondBaseStorage } from './DiamondBaseStorage.sol' ;
import {IDiamondLoupe } from './IDiamondLoupe.sol' ;
abstract contract DiamondLoupe is IDiamondLoupe {
function facets ( ) external override view returns (Facet[] memory diamondFacets ) {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
diamondFacets = new Facet[](l.selectorCount);
uint8 [] memory numFacetSelectors = new uint8 [](l.selectorCount);
uint256 numFacets;
uint256 selectorIndex;
for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex+ + ) {
bytes32 slot = l.selectorSlots[slotIndex];
for (uint256 selectorSlotIndex; selectorSlotIndex < 8 ; selectorSlotIndex+ + ) {
selectorIndex+ + ;
if (selectorIndex > l.selectorCount) {
break ;
}
bytes4 selector = bytes4 (slot < < (selectorSlotIndex < < 5 ));
address facet = address (bytes20 (l.facets[selector]));
bool continueLoop;
for (uint256 facetIndex; facetIndex < numFacets; facetIndex+ + ) {
if (diamondFacets[facetIndex].target = = facet) {
diamondFacets[facetIndex].selectors[numFacetSelectors[facetIndex]] = selector;
require (numFacetSelectors[facetIndex] < 255 );
numFacetSelectors[facetIndex]+ + ;
continueLoop = true ;
break ;
}
}
if (continueLoop) {
continue ;
}
diamondFacets[numFacets].target = facet;
diamondFacets[numFacets].selectors = new bytes4 [](l.selectorCount);
diamondFacets[numFacets].selectors[0 ] = selector;
numFacetSelectors[numFacets] = 1 ;
numFacets+ + ;
}
}
for (uint256 facetIndex; facetIndex < numFacets; facetIndex+ + ) {
uint256 numSelectors = numFacetSelectors[facetIndex];
bytes4 [] memory selectors = diamondFacets[facetIndex].selectors;
assembly { mstore (selectors, numSelectors) }
}
assembly { mstore (diamondFacets, numFacets) }
}
function facetFunctionSelectors (
address facet
) external override view returns (bytes4 [] memory selectors ) {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
selectors = new bytes4 [](l.selectorCount);
uint256 numSelectors;
uint256 selectorIndex;
for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex+ + ) {
bytes32 slot = l.selectorSlots[slotIndex];
for (uint256 selectorSlotIndex; selectorSlotIndex < 8 ; selectorSlotIndex+ + ) {
selectorIndex+ + ;
if (selectorIndex > l.selectorCount) {
break ;
}
bytes4 selector = bytes4 (slot < < (selectorSlotIndex < < 5 ));
if (facet = = address (bytes20 (l.facets[selector]))) {
selectors[numSelectors] = selector;
numSelectors+ + ;
}
}
}
assembly { mstore (selectors, numSelectors) }
}
function facetAddresses ( ) external override view returns (address [] memory addresses ) {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
addresses = new address [](l.selectorCount);
uint256 numFacets;
uint256 selectorIndex;
for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex+ + ) {
bytes32 slot = l.selectorSlots[slotIndex];
for (uint256 selectorSlotIndex; selectorSlotIndex < 8 ; selectorSlotIndex+ + ) {
selectorIndex+ + ;
if (selectorIndex > l.selectorCount) {
break ;
}
bytes4 selector = bytes4 (slot < < (selectorSlotIndex < < 5 ));
address facet = address (bytes20 (l.facets[selector]));
bool continueLoop;
for (uint256 facetIndex; facetIndex < numFacets; facetIndex+ + ) {
if (facet = = addresses[facetIndex]) {
continueLoop = true ;
break ;
}
}
if (continueLoop) {
continue ;
}
addresses[numFacets] = facet;
numFacets+ + ;
}
}
assembly { mstore (addresses, numFacets) }
}
function facetAddress (
bytes4 selector
) external override view returns (address facet ) {
facet = address (bytes20 (
DiamondBaseStorage.layout().facets[selector]
));
}
}
File 7 of 21: ERC165.sol
pragma solidity ^0.8.0;
import {IERC165 } from './IERC165.sol' ;
import {ERC165Storage } from './ERC165Storage.sol' ;
abstract contract ERC165 is IERC165 {
using ERC165Storage for ERC165Storage .Layout ;
function supportsInterface (bytes4 interfaceId ) override public view returns (bool ) {
return ERC165Storage.layout().isSupportedInterface(interfaceId);
}
}
File 8 of 21: ERC165Storage.sol
pragma solidity ^0.8.0;
library ERC165Storage {
struct Layout {
mapping (bytes4 = > bool ) supportedInterfaces;
}
bytes32 internal constant STORAGE_SLOT = keccak256 (
'solidstate.contracts.storage.ERC165'
);
function layout ( ) internal pure returns (Layout storage l ) {
bytes32 slot = STORAGE_SLOT;
assembly { l.slot := slot }
}
function isSupportedInterface (
Layout storage l,
bytes4 interfaceId
) internal view returns (bool ) {
return l.supportedInterfaces[interfaceId];
}
function setSupportedInterface (
Layout storage l,
bytes4 interfaceId,
bool status
) internal {
require (interfaceId ! = 0xffffffff , 'ERC165: invalid interface id' );
l.supportedInterfaces[interfaceId] = status;
}
}
File 9 of 21: ERC20MetadataStorage.sol
pragma solidity ^0.8.0;
library ERC20MetadataStorage {
struct Layout {
string name;
string symbol;
uint8 decimals;
}
bytes32 internal constant STORAGE_SLOT = keccak256 (
'solidstate.contracts.storage.ERC20Metadata'
);
function layout ( ) internal pure returns (Layout storage l ) {
bytes32 slot = STORAGE_SLOT;
assembly { l.slot := slot }
}
function setName (
Layout storage l,
string memory name
) internal {
l.name = name;
}
function setSymbol (
Layout storage l,
string memory symbol
) internal {
l.symbol = symbol;
}
function setDecimals (
Layout storage l,
uint8 decimals
) internal {
l.decimals = decimals;
}
}
File 10 of 21: IDiamondCuttable.sol
pragma solidity ^0.8.0;
interface IDiamondCuttable {
enum FacetCutAction { ADD, REPLACE, REMOVE }
event DiamondCut (FacetCut[] facetCuts, address target, bytes data ) ;
struct FacetCut {
address target;
FacetCutAction action;
bytes4 [] selectors;
}
function diamondCut (
FacetCut[] calldata facetCuts,
address target,
bytes calldata data
) external ;
}
File 11 of 21: IDiamondLoupe.sol
pragma solidity ^0.8.0;
interface IDiamondLoupe {
struct Facet {
address target;
bytes4 [] selectors;
}
function facets ( ) external view returns (Facet[] memory diamondFacets ) ;
function facetFunctionSelectors (
address facet
) external view returns (bytes4 [] memory selectors ) ;
function facetAddresses ( ) external view returns (address [] memory addresses ) ;
function facetAddress (
bytes4 selector
) external view returns (address facet ) ;
}
File 12 of 21: IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface (
bytes4 interfaceId
) external view returns (bool ) ;
}
File 13 of 21: IERC173.sol
pragma solidity ^0.8.0;
interface IERC173 {
event OwnershipTransferred (address indexed previousOwner, address indexed newOwner ) ;
function owner ( ) external view returns (address ) ;
function transferOwnership (address account ) external ;
}
File 14 of 21: MagicProxy.sol
pragma solidity ^0.8.0;
import '@solidstate/contracts/proxy/diamond/Diamond.sol' ;
import '@solidstate/contracts/token/ERC20/metadata/ERC20MetadataStorage.sol' ;
contract MagicProxy is Diamond {
constructor ( ) {
ERC20MetadataStorage.Layout storage l = ERC20MetadataStorage.layout();
l.name = 'MAGIC' ;
l.symbol = 'MAGIC' ;
}
}
File 15 of 21: Ownable.sol
pragma solidity ^0.8.0;
import {IERC173 } from './IERC173.sol' ;
import {OwnableInternal } from './OwnableInternal.sol' ;
import {OwnableStorage } from './OwnableStorage.sol' ;
abstract contract Ownable is IERC173 , OwnableInternal {
using OwnableStorage for OwnableStorage .Layout ;
function owner ( ) virtual override public view returns (address ) {
return OwnableStorage.layout().owner;
}
function transferOwnership (
address account
) virtual override public onlyOwner {
OwnableStorage.layout().setOwner(account);
emit OwnershipTransferred(msg .sender , account);
}
}
File 16 of 21: OwnableInternal.sol
pragma solidity ^0.8.0;
import {OwnableStorage } from './OwnableStorage.sol' ;
abstract contract OwnableInternal {
using OwnableStorage for OwnableStorage .Layout ;
modifier onlyOwner {
require (
msg .sender = = OwnableStorage.layout().owner,
'Ownable: sender must be owner'
);
_ ;
}
}
File 17 of 21: OwnableStorage.sol
pragma solidity ^0.8.0;
library OwnableStorage {
struct Layout {
address owner;
}
bytes32 internal constant STORAGE_SLOT = keccak256 (
'solidstate.contracts.storage.Ownable'
);
function layout ( ) internal pure returns (Layout storage l ) {
bytes32 slot = STORAGE_SLOT;
assembly { l.slot := slot }
}
function setOwner (
Layout storage l,
address owner
) internal {
l.owner = owner;
}
}
File 18 of 21: Proxy.sol
pragma solidity ^0.8.0;
import {AddressUtils } from '../utils/AddressUtils.sol' ;
abstract contract Proxy {
using AddressUtils for address ;
fallback ( ) virtual external payable {
address implementation = _getImplementation();
require (
implementation.isContract(),
'Proxy: implementation must be contract'
);
assembly {
calldatacopy (0 , 0 , calldatasize ())
let result := delegatecall (gas (), implementation, 0 , calldatasize (), 0 , 0 )
returndatacopy (0 , 0 , returndatasize ())
switch result
case 0 { revert (0 , returndatasize ()) }
default { return (0 , returndatasize ()) }
}
}
function _getImplementation ( ) virtual internal returns (address ) ;
}
File 19 of 21: SafeOwnable.sol
pragma solidity ^0.8.0;
import {Ownable , OwnableStorage } from './Ownable.sol' ;
import {SafeOwnableInternal } from './SafeOwnableInternal.sol' ;
import {SafeOwnableStorage } from './SafeOwnableStorage.sol' ;
abstract contract SafeOwnable is Ownable , SafeOwnableInternal {
using OwnableStorage for OwnableStorage .Layout ;
using SafeOwnableStorage for SafeOwnableStorage .Layout ;
function nomineeOwner ( ) virtual public view returns (address ) {
return SafeOwnableStorage.layout().nomineeOwner;
}
function transferOwnership (
address account
) virtual override public onlyOwner {
SafeOwnableStorage.layout().setNomineeOwner(account);
}
function acceptOwnership ( ) virtual public onlyNomineeOwner {
OwnableStorage.Layout storage l = OwnableStorage.layout();
emit OwnershipTransferred(l.owner, msg .sender );
l.setOwner(msg .sender );
SafeOwnableStorage.layout().setNomineeOwner(address (0 ));
}
}
File 20 of 21: SafeOwnableInternal.sol
pragma solidity ^0.8.0;
import {SafeOwnableStorage } from './SafeOwnableStorage.sol' ;
abstract contract SafeOwnableInternal {
using SafeOwnableStorage for SafeOwnableStorage .Layout ;
modifier onlyNomineeOwner ( ) {
require (
msg .sender = = SafeOwnableStorage.layout().nomineeOwner,
'SafeOwnable: sender must be nominee owner'
);
_ ;
}
}
File 21 of 21: SafeOwnableStorage.sol
pragma solidity ^0.8.0;
library SafeOwnableStorage {
struct Layout {
address nomineeOwner;
}
bytes32 internal constant STORAGE_SLOT = keccak256 (
'solidstate.contracts.storage.SafeOwnable'
);
function layout ( ) internal pure returns (Layout storage l ) {
bytes32 slot = STORAGE_SLOT;
assembly { l.slot := slot }
}
function setNomineeOwner (
Layout storage l,
address nomineeOwner
) internal {
l.nomineeOwner = nomineeOwner;
}
}
{
"compilationTarget" : {
"contracts/token/MagicProxy.sol" : "MagicProxy"
} ,
"evmVersion" : "istanbul" ,
"libraries" : { } ,
"metadata" : {
"bytecodeHash" : "ipfs"
} ,
"optimizer" : {
"enabled" : true ,
"runs" : 200
} ,
"remappings" : [ ]
} [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondCuttable.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondCuttable.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"DiamondCut","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondCuttable.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondCuttable.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondLoupe.Facet[]","name":"diamondFacets","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]