// SPDX-License-Identifier: CC0-1.0pragmasolidity >=0.8.13;/**
* @title IDelegateRegistry
* @custom:version 2.0
* @custom:author foobar (0xfoobar)
* @notice A standalone immutable registry storing delegated permissions from one address to another
*/interfaceIDelegateRegistry{
/// @notice Delegation type, NONE is used when a delegation does not exist or is revokedenumDelegationType {
NONE,
ALL,
CONTRACT,
ERC721,
ERC20,
ERC1155
}
/// @notice Struct for returning delegationsstructDelegation {
DelegationType type_;
address to;
addressfrom;
bytes32 rights;
address contract_;
uint256 tokenId;
uint256 amount;
}
/// @notice Emitted when an address delegates or revokes rights for their entire walleteventDelegateAll(addressindexedfrom, addressindexed to, bytes32 rights, bool enable);
/// @notice Emitted when an address delegates or revokes rights for a contract addresseventDelegateContract(addressindexedfrom, addressindexed to, addressindexed contract_, bytes32 rights, bool enable);
/// @notice Emitted when an address delegates or revokes rights for an ERC721 tokenIdeventDelegateERC721(addressindexedfrom, addressindexed to, addressindexed contract_, uint256 tokenId, bytes32 rights, bool enable);
/// @notice Emitted when an address delegates or revokes rights for an amount of ERC20 tokenseventDelegateERC20(addressindexedfrom, addressindexed to, addressindexed contract_, bytes32 rights, uint256 amount);
/// @notice Emitted when an address delegates or revokes rights for an amount of an ERC1155 tokenIdeventDelegateERC1155(addressindexedfrom, addressindexed to, addressindexed contract_, uint256 tokenId, bytes32 rights, uint256 amount);
/// @notice Thrown if multicall calldata is malformederrorMulticallFailed();
/**
* ----------- WRITE -----------
*//**
* @notice Call multiple functions in the current contract and return the data from all of them if they all succeed
* @param data The encoded function data for each of the calls to make to this contract
* @return results The results from each of the calls passed in via data
*/functionmulticall(bytes[] calldata data) externalpayablereturns (bytes[] memory results);
/**
* @notice Allow the delegate to act on behalf of `msg.sender` for all contracts
* @param to The address to act as delegate
* @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
* @param enable Whether to enable or disable this delegation, true delegates and false revokes
* @return delegationHash The unique identifier of the delegation
*/functiondelegateAll(address to, bytes32 rights, bool enable) externalpayablereturns (bytes32 delegationHash);
/**
* @notice Allow the delegate to act on behalf of `msg.sender` for a specific contract
* @param to The address to act as delegate
* @param contract_ The contract whose rights are being delegated
* @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
* @param enable Whether to enable or disable this delegation, true delegates and false revokes
* @return delegationHash The unique identifier of the delegation
*/functiondelegateContract(address to, address contract_, bytes32 rights, bool enable) externalpayablereturns (bytes32 delegationHash);
/**
* @notice Allow the delegate to act on behalf of `msg.sender` for a specific ERC721 token
* @param to The address to act as delegate
* @param contract_ The contract whose rights are being delegated
* @param tokenId The token id to delegate
* @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
* @param enable Whether to enable or disable this delegation, true delegates and false revokes
* @return delegationHash The unique identifier of the delegation
*/functiondelegateERC721(address to, address contract_, uint256 tokenId, bytes32 rights, bool enable) externalpayablereturns (bytes32 delegationHash);
/**
* @notice Allow the delegate to act on behalf of `msg.sender` for a specific amount of ERC20 tokens
* @dev The actual amount is not encoded in the hash, just the existence of a amount (since it is an upper bound)
* @param to The address to act as delegate
* @param contract_ The address for the fungible token contract
* @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
* @param amount The amount to delegate, > 0 delegates and 0 revokes
* @return delegationHash The unique identifier of the delegation
*/functiondelegateERC20(address to, address contract_, bytes32 rights, uint256 amount) externalpayablereturns (bytes32 delegationHash);
/**
* @notice Allow the delegate to act on behalf of `msg.sender` for a specific amount of ERC1155 tokens
* @dev The actual amount is not encoded in the hash, just the existence of a amount (since it is an upper bound)
* @param to The address to act as delegate
* @param contract_ The address of the contract that holds the token
* @param tokenId The token id to delegate
* @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
* @param amount The amount of that token id to delegate, > 0 delegates and 0 revokes
* @return delegationHash The unique identifier of the delegation
*/functiondelegateERC1155(address to, address contract_, uint256 tokenId, bytes32 rights, uint256 amount) externalpayablereturns (bytes32 delegationHash);
/**
* ----------- CHECKS -----------
*//**
* @notice Check if `to` is a delegate of `from` for the entire wallet
* @param to The potential delegate address
* @param from The potential address who delegated rights
* @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
* @return valid Whether delegate is granted to act on the from's behalf
*/functioncheckDelegateForAll(address to, addressfrom, bytes32 rights) externalviewreturns (bool);
/**
* @notice Check if `to` is a delegate of `from` for the specified `contract_` or the entire wallet
* @param to The delegated address to check
* @param contract_ The specific contract address being checked
* @param from The cold wallet who issued the delegation
* @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
* @return valid Whether delegate is granted to act on from's behalf for entire wallet or that specific contract
*/functioncheckDelegateForContract(address to, addressfrom, address contract_, bytes32 rights) externalviewreturns (bool);
/**
* @notice Check if `to` is a delegate of `from` for the specific `contract` and `tokenId`, the entire `contract_`, or the entire wallet
* @param to The delegated address to check
* @param contract_ The specific contract address being checked
* @param tokenId The token id for the token to delegating
* @param from The wallet that issued the delegation
* @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
* @return valid Whether delegate is granted to act on from's behalf for entire wallet, that contract, or that specific tokenId
*/functioncheckDelegateForERC721(address to, addressfrom, address contract_, uint256 tokenId, bytes32 rights) externalviewreturns (bool);
/**
* @notice Returns the amount of ERC20 tokens the delegate is granted rights to act on the behalf of
* @param to The delegated address to check
* @param contract_ The address of the token contract
* @param from The cold wallet who issued the delegation
* @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
* @return balance The delegated balance, which will be 0 if the delegation does not exist
*/functioncheckDelegateForERC20(address to, addressfrom, address contract_, bytes32 rights) externalviewreturns (uint256);
/**
* @notice Returns the amount of a ERC1155 tokens the delegate is granted rights to act on the behalf of
* @param to The delegated address to check
* @param contract_ The address of the token contract
* @param tokenId The token id to check the delegated amount of
* @param from The cold wallet who issued the delegation
* @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
* @return balance The delegated balance, which will be 0 if the delegation does not exist
*/functioncheckDelegateForERC1155(address to, addressfrom, address contract_, uint256 tokenId, bytes32 rights) externalviewreturns (uint256);
/**
* ----------- ENUMERATIONS -----------
*//**
* @notice Returns all enabled delegations a given delegate has received
* @param to The address to retrieve delegations for
* @return delegations Array of Delegation structs
*/functiongetIncomingDelegations(address to) externalviewreturns (Delegation[] memory delegations);
/**
* @notice Returns all enabled delegations an address has given out
* @param from The address to retrieve delegations for
* @return delegations Array of Delegation structs
*/functiongetOutgoingDelegations(addressfrom) externalviewreturns (Delegation[] memory delegations);
/**
* @notice Returns all hashes associated with enabled delegations an address has received
* @param to The address to retrieve incoming delegation hashes for
* @return delegationHashes Array of delegation hashes
*/functiongetIncomingDelegationHashes(address to) externalviewreturns (bytes32[] memory delegationHashes);
/**
* @notice Returns all hashes associated with enabled delegations an address has given out
* @param from The address to retrieve outgoing delegation hashes for
* @return delegationHashes Array of delegation hashes
*/functiongetOutgoingDelegationHashes(addressfrom) externalviewreturns (bytes32[] memory delegationHashes);
/**
* @notice Returns the delegations for a given array of delegation hashes
* @param delegationHashes is an array of hashes that correspond to delegations
* @return delegations Array of Delegation structs, return empty structs for nonexistent or revoked delegations
*/functiongetDelegationsFromHashes(bytes32[] calldata delegationHashes) externalviewreturns (Delegation[] memory delegations);
/**
* ----------- STORAGE ACCESS -----------
*//**
* @notice Allows external contracts to read arbitrary storage slots
*/functionreadSlot(bytes32 location) externalviewreturns (bytes32);
/**
* @notice Allows external contracts to read an arbitrary array of storage slots
*/functionreadSlots(bytes32[] calldata locations) externalviewreturns (bytes32[] memory);
}
// SPDX-License-Identifier: MITpragmasolidity ^0.8.4;/// @notice Library for storage of packed unsigned integers./// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibMap.sol)libraryLibMap{
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* STRUCTS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev A uint8 map in storage.structUint8Map {
mapping(uint256=>uint256) map;
}
/// @dev A uint16 map in storage.structUint16Map {
mapping(uint256=>uint256) map;
}
/// @dev A uint32 map in storage.structUint32Map {
mapping(uint256=>uint256) map;
}
/// @dev A uint40 map in storage. Useful for storing timestamps up to 34841 A.D.structUint40Map {
mapping(uint256=>uint256) map;
}
/// @dev A uint64 map in storage.structUint64Map {
mapping(uint256=>uint256) map;
}
/// @dev A uint128 map in storage.structUint128Map {
mapping(uint256=>uint256) map;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* GETTERS / SETTERS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Returns the uint8 value at `index` in `map`.functionget(Uint8Map storage map, uint256 index) internalviewreturns (uint8 result) {
/// @solidity memory-safe-assemblyassembly {
mstore(0x20, map.slot)
mstore(0x00, shr(5, index))
result :=byte(and(31, not(index)), sload(keccak256(0x00, 0x40)))
}
}
/// @dev Updates the uint8 value at `index` in `map`.functionset(Uint8Map storage map, uint256 index, uint8 value) internal{
/// @solidity memory-safe-assemblyassembly {
mstore(0x20, map.slot)
mstore(0x00, shr(5, index))
let s :=keccak256(0x00, 0x40) // Storage slot.mstore(0x00, sload(s))
mstore8(and(31, not(index)), value)
sstore(s, mload(0x00))
}
}
/// @dev Returns the uint16 value at `index` in `map`.functionget(Uint16Map storage map, uint256 index) internalviewreturns (uint16 result) {
result =uint16(map.map[index >>4] >> ((index &15) <<4));
}
/// @dev Updates the uint16 value at `index` in `map`.functionset(Uint16Map storage map, uint256 index, uint16 value) internal{
/// @solidity memory-safe-assemblyassembly {
mstore(0x20, map.slot)
mstore(0x00, shr(4, index))
let s :=keccak256(0x00, 0x40) // Storage slot.let o :=shl(4, and(index, 15)) // Storage slot offset (bits).let v :=sload(s) // Storage slot value.let m :=0xffff// Value mask.sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
}
}
/// @dev Returns the uint32 value at `index` in `map`.functionget(Uint32Map storage map, uint256 index) internalviewreturns (uint32 result) {
result =uint32(map.map[index >>3] >> ((index &7) <<5));
}
/// @dev Updates the uint32 value at `index` in `map`.functionset(Uint32Map storage map, uint256 index, uint32 value) internal{
/// @solidity memory-safe-assemblyassembly {
mstore(0x20, map.slot)
mstore(0x00, shr(3, index))
let s :=keccak256(0x00, 0x40) // Storage slot.let o :=shl(5, and(index, 7)) // Storage slot offset (bits).let v :=sload(s) // Storage slot value.let m :=0xffffffff// Value mask.sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
}
}
/// @dev Returns the uint40 value at `index` in `map`.functionget(Uint40Map storage map, uint256 index) internalviewreturns (uint40 result) {
unchecked {
result =uint40(map.map[index /6] >> ((index %6) *40));
}
}
/// @dev Updates the uint40 value at `index` in `map`.functionset(Uint40Map storage map, uint256 index, uint40 value) internal{
/// @solidity memory-safe-assemblyassembly {
mstore(0x20, map.slot)
mstore(0x00, div(index, 6))
let s :=keccak256(0x00, 0x40) // Storage slot.let o :=mul(40, mod(index, 6)) // Storage slot offset (bits).let v :=sload(s) // Storage slot value.let m :=0xffffffffff// Value mask.sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
}
}
/// @dev Returns the uint64 value at `index` in `map`.functionget(Uint64Map storage map, uint256 index) internalviewreturns (uint64 result) {
result =uint64(map.map[index >>2] >> ((index &3) <<6));
}
/// @dev Updates the uint64 value at `index` in `map`.functionset(Uint64Map storage map, uint256 index, uint64 value) internal{
/// @solidity memory-safe-assemblyassembly {
mstore(0x20, map.slot)
mstore(0x00, shr(2, index))
let s :=keccak256(0x00, 0x40) // Storage slot.let o :=shl(6, and(index, 3)) // Storage slot offset (bits).let v :=sload(s) // Storage slot value.let m :=0xffffffffffffffff// Value mask.sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
}
}
/// @dev Returns the uint128 value at `index` in `map`.functionget(Uint128Map storage map, uint256 index) internalviewreturns (uint128 result) {
result =uint128(map.map[index >>1] >> ((index &1) <<7));
}
/// @dev Updates the uint128 value at `index` in `map`.functionset(Uint128Map storage map, uint256 index, uint128 value) internal{
/// @solidity memory-safe-assemblyassembly {
mstore(0x20, map.slot)
mstore(0x00, shr(1, index))
let s :=keccak256(0x00, 0x40) // Storage slot.let o :=shl(7, and(index, 1)) // Storage slot offset (bits).let v :=sload(s) // Storage slot value.let m :=0xffffffffffffffffffffffffffffffff// Value mask.sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
}
}
/// @dev Returns the value at `index` in `map`.functionget(mapping(uint256 => uint256) storage map, uint256 index, uint256 bitWidth)
internalviewreturns (uint256 result)
{
unchecked {
uint256 d = _rawDiv(256, bitWidth); // Bucket size.uint256 m = (1<< bitWidth) -1; // Value mask.
result = (map[_rawDiv(index, d)] >> (_rawMod(index, d) * bitWidth)) & m;
}
}
/// @dev Updates the value at `index` in `map`.functionset(mapping(uint256 => uint256) storage map,
uint256 index,
uint256 value,
uint256 bitWidth
) internal{
unchecked {
uint256 d = _rawDiv(256, bitWidth); // Bucket size.uint256 m = (1<< bitWidth) -1; // Value mask.uint256 o = _rawMod(index, d) * bitWidth; // Storage slot offset (bits).
map[_rawDiv(index, d)] ^= (((map[_rawDiv(index, d)] >> o) ^ value) & m) << o;
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* BINARY SEARCH *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/// The following functions search in the range of [`start`, `end`)// (i.e. `start <= index < end`).// The range must be sorted in ascending order.// `index` precedence: equal to > nearest before > nearest after.// An invalid search range will simply return `(found = false, index = start)`./// @dev Returns whether `map` contains `needle`, and the index of `needle`.functionsearchSorted(Uint8Map storage map, uint8 needle, uint256 start, uint256 end)
internalviewreturns (bool found, uint256 index)
{
return searchSorted(map.map, needle, start, end, 8);
}
/// @dev Returns whether `map` contains `needle`, and the index of `needle`.functionsearchSorted(Uint16Map storage map, uint16 needle, uint256 start, uint256 end)
internalviewreturns (bool found, uint256 index)
{
return searchSorted(map.map, needle, start, end, 16);
}
/// @dev Returns whether `map` contains `needle`, and the index of `needle`.functionsearchSorted(Uint32Map storage map, uint32 needle, uint256 start, uint256 end)
internalviewreturns (bool found, uint256 index)
{
return searchSorted(map.map, needle, start, end, 32);
}
/// @dev Returns whether `map` contains `needle`, and the index of `needle`.functionsearchSorted(Uint40Map storage map, uint40 needle, uint256 start, uint256 end)
internalviewreturns (bool found, uint256 index)
{
return searchSorted(map.map, needle, start, end, 40);
}
/// @dev Returns whether `map` contains `needle`, and the index of `needle`.functionsearchSorted(Uint64Map storage map, uint64 needle, uint256 start, uint256 end)
internalviewreturns (bool found, uint256 index)
{
return searchSorted(map.map, needle, start, end, 64);
}
/// @dev Returns whether `map` contains `needle`, and the index of `needle`.functionsearchSorted(Uint128Map storage map, uint128 needle, uint256 start, uint256 end)
internalviewreturns (bool found, uint256 index)
{
return searchSorted(map.map, needle, start, end, 128);
}
/// @dev Returns whether `map` contains `needle`, and the index of `needle`.functionsearchSorted(mapping(uint256 => uint256) storage map,
uint256 needle,
uint256 start,
uint256 end,
uint256 bitWidth
) internalviewreturns (bool found, uint256 index) {
unchecked {
if (start >= end) end = start;
uint256 t;
uint256 o = start -1; // Offset to derive the actual index.uint256 l =1; // Low.uint256 d = _rawDiv(256, bitWidth); // Bucket size.uint256 m = (1<< bitWidth) -1; // Value mask.uint256 h = end - start; // High.while (true) {
index = (l & h) + ((l ^ h) >>1);
if (l > h) break;
t = (map[_rawDiv(index + o, d)] >> (_rawMod(index + o, d) * bitWidth)) & m;
if (t == needle) break;
if (needle <= t) h = index -1;
else l = index +1;
}
/// @solidity memory-safe-assemblyassembly {
m :=or(iszero(index), iszero(bitWidth))
found :=iszero(or(xor(t, needle), m))
index :=add(o, xor(index, mul(xor(index, 1), m)))
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* PRIVATE HELPERS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Returns `x / y`, returning 0 if `y` is zero.function_rawDiv(uint256 x, uint256 y) privatepurereturns (uint256 z) {
/// @solidity memory-safe-assemblyassembly {
z :=div(x, y)
}
}
/// @dev Returns `x % y`, returning 0 if `y` is zero.function_rawMod(uint256 x, uint256 y) privatepurereturns (uint256 z) {
/// @solidity memory-safe-assemblyassembly {
z :=mod(x, y)
}
}
}
Contract Source Code
File 5 of 7: Ownable.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.4;/// @notice Simple single owner authorization mixin./// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)////// @dev Note:/// This implementation does NOT auto-initialize the owner to `msg.sender`./// You MUST call the `_initializeOwner` in the constructor / initializer.////// While the ownable portion follows/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,/// the nomenclature for the 2-step ownership handover may be unique to this codebase.abstractcontractOwnable{
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* CUSTOM ERRORS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev The caller is not authorized to call the function.errorUnauthorized();
/// @dev The `newOwner` cannot be the zero address.errorNewOwnerIsZeroAddress();
/// @dev The `pendingOwner` does not have a valid handover request.errorNoHandoverRequest();
/// @dev Cannot double-initialize.errorAlreadyInitialized();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* EVENTS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev The ownership is transferred from `oldOwner` to `newOwner`./// This event is intentionally kept the same as OpenZeppelin's Ownable to be/// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),/// despite it not being as lightweight as a single argument event.eventOwnershipTransferred(addressindexed oldOwner, addressindexed newOwner);
/// @dev An ownership handover to `pendingOwner` has been requested.eventOwnershipHandoverRequested(addressindexed pendingOwner);
/// @dev The ownership handover to `pendingOwner` has been canceled.eventOwnershipHandoverCanceled(addressindexed pendingOwner);
/// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.uint256privateconstant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
/// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.uint256privateconstant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
/// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.uint256privateconstant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* STORAGE *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev The owner slot is given by:/// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`./// It is intentionally chosen to be a high value/// to avoid collision with lower slots./// The choice of manual storage layout is to enable compatibility/// with both regular and upgradeable contracts.bytes32internalconstant _OWNER_SLOT =0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;
/// The ownership handover slot of `newOwner` is given by:/// ```/// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))/// let handoverSlot := keccak256(0x00, 0x20)/// ```/// It stores the expiry timestamp of the two-step ownership handover.uint256privateconstant _HANDOVER_SLOT_SEED =0x389a75e1;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* INTERNAL FUNCTIONS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Override to return true to make `_initializeOwner` prevent double-initialization.function_guardInitializeOwner() internalpurevirtualreturns (bool guard) {}
/// @dev Initializes the owner directly without authorization guard./// This function must be called upon initialization,/// regardless of whether the contract is upgradeable or not./// This is to enable generalization to both regular and upgradeable contracts,/// and to save gas in case the initial owner is not the caller./// For performance reasons, this function will not check if there/// is an existing owner.function_initializeOwner(address newOwner) internalvirtual{
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assemblyassembly {
let ownerSlot := _OWNER_SLOT
ifsload(ownerSlot) {
mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.revert(0x1c, 0x04)
}
// Clean the upper 96 bits.
newOwner :=shr(96, shl(96, newOwner))
// Store the new value.sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
// Emit the {OwnershipTransferred} event.log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
} else {
/// @solidity memory-safe-assemblyassembly {
// Clean the upper 96 bits.
newOwner :=shr(96, shl(96, newOwner))
// Store the new value.sstore(_OWNER_SLOT, newOwner)
// Emit the {OwnershipTransferred} event.log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
}
/// @dev Sets the owner directly without authorization guard.function_setOwner(address newOwner) internalvirtual{
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assemblyassembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner :=shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
}
} else {
/// @solidity memory-safe-assemblyassembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner :=shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.sstore(ownerSlot, newOwner)
}
}
}
/// @dev Throws if the sender is not the owner.function_checkOwner() internalviewvirtual{
/// @solidity memory-safe-assemblyassembly {
// If the caller is not the stored owner, revert.ifiszero(eq(caller(), sload(_OWNER_SLOT))) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.revert(0x1c, 0x04)
}
}
}
/// @dev Returns how long a two-step ownership handover is valid for in seconds./// Override to return a different value if needed./// Made internal to conserve bytecode. Wrap it in a public function if needed.function_ownershipHandoverValidFor() internalviewvirtualreturns (uint64) {
return48*3600;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* PUBLIC UPDATE FUNCTIONS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Allows the owner to transfer the ownership to `newOwner`.functiontransferOwnership(address newOwner) publicpayablevirtualonlyOwner{
/// @solidity memory-safe-assemblyassembly {
ifiszero(shl(96, newOwner)) {
mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
/// @dev Allows the owner to renounce their ownership.functionrenounceOwnership() publicpayablevirtualonlyOwner{
_setOwner(address(0));
}
/// @dev Request a two-step ownership handover to the caller./// The request will automatically expire in 48 hours (172800 seconds) by default.functionrequestOwnershipHandover() publicpayablevirtual{
unchecked {
uint256 expires =block.timestamp+ _ownershipHandoverValidFor();
/// @solidity memory-safe-assemblyassembly {
// Compute and set the handover slot to `expires`.mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
// Emit the {OwnershipHandoverRequested} event.log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
/// @dev Cancels the two-step ownership handover to the caller, if any.functioncancelOwnershipHandover() publicpayablevirtual{
/// @solidity memory-safe-assemblyassembly {
// Compute and set the handover slot to 0.mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
// Emit the {OwnershipHandoverCanceled} event.log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
/// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`./// Reverts if there is no existing ownership handover requested by `pendingOwner`.functioncompleteOwnershipHandover(address pendingOwner) publicpayablevirtualonlyOwner{
/// @solidity memory-safe-assemblyassembly {
// Compute and set the handover slot to 0.mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot :=keccak256(0x0c, 0x20)
// If the handover does not exist, or has expired.ifgt(timestamp(), sload(handoverSlot)) {
mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.revert(0x1c, 0x04)
}
// Set the handover slot to 0.sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* PUBLIC READ FUNCTIONS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Returns the owner of the contract.functionowner() publicviewvirtualreturns (address result) {
/// @solidity memory-safe-assemblyassembly {
result :=sload(_OWNER_SLOT)
}
}
/// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.functionownershipHandoverExpiresAt(address pendingOwner)
publicviewvirtualreturns (uint256 result)
{
/// @solidity memory-safe-assemblyassembly {
// Compute the handover slot.mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
// Load the handover slot.
result :=sload(keccak256(0x0c, 0x20))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* MODIFIERS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Marks a function as only callable by the owner.modifieronlyOwner() virtual{
_checkOwner();
_;
}
}
Contract Source Code
File 6 of 7: OwnableRoles.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.4;import {Ownable} from"./Ownable.sol";
/// @notice Simple single owner and multiroles authorization mixin./// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)/// for compatibility, the nomenclature for the 2-step ownership handover and roles/// may be unique to this codebase.abstractcontractOwnableRolesisOwnable{
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* EVENTS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev The `user`'s roles is updated to `roles`./// Each bit of `roles` represents whether the role is set.eventRolesUpdated(addressindexed user, uint256indexed roles);
/// @dev `keccak256(bytes("RolesUpdated(address,uint256)"))`.uint256privateconstant _ROLES_UPDATED_EVENT_SIGNATURE =0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* STORAGE *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev The role slot of `user` is given by:/// ```/// mstore(0x00, or(shl(96, user), _ROLE_SLOT_SEED))/// let roleSlot := keccak256(0x00, 0x20)/// ```/// This automatically ignores the upper bits of the `user` in case/// they are not clean, as well as keep the `keccak256` under 32-bytes.////// Note: This is equivalent to `uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))`.uint256privateconstant _ROLE_SLOT_SEED =0x8b78c6d8;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* INTERNAL FUNCTIONS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Overwrite the roles directly without authorization guard.function_setRoles(address user, uint256 roles) internalvirtual{
/// @solidity memory-safe-assemblyassembly {
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
// Store the new value.sstore(keccak256(0x0c, 0x20), roles)
// Emit the {RolesUpdated} event.log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles)
}
}
/// @dev Updates the roles directly without authorization guard./// If `on` is true, each set bit of `roles` will be turned on,/// otherwise, each set bit of `roles` will be turned off.function_updateRoles(address user, uint256 roles, bool on) internalvirtual{
/// @solidity memory-safe-assemblyassembly {
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
let roleSlot :=keccak256(0x0c, 0x20)
// Load the current value.let current :=sload(roleSlot)
// Compute the updated roles if `on` is true.let updated :=or(current, roles)
// Compute the updated roles if `on` is false.// Use `and` to compute the intersection of `current` and `roles`,// `xor` it with `current` to flip the bits in the intersection.ifiszero(on) { updated :=xor(current, and(current, roles)) }
// Then, store the new value.sstore(roleSlot, updated)
// Emit the {RolesUpdated} event.log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), updated)
}
}
/// @dev Grants the roles directly without authorization guard./// Each bit of `roles` represents the role to turn on.function_grantRoles(address user, uint256 roles) internalvirtual{
_updateRoles(user, roles, true);
}
/// @dev Removes the roles directly without authorization guard./// Each bit of `roles` represents the role to turn off.function_removeRoles(address user, uint256 roles) internalvirtual{
_updateRoles(user, roles, false);
}
/// @dev Throws if the sender does not have any of the `roles`.function_checkRoles(uint256 roles) internalviewvirtual{
/// @solidity memory-safe-assemblyassembly {
// Compute the role slot.mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, caller())
// Load the stored value, and if the `and` intersection// of the value and `roles` is zero, revert.ifiszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.revert(0x1c, 0x04)
}
}
}
/// @dev Throws if the sender is not the owner,/// and does not have any of the `roles`./// Checks for ownership first, then lazily checks for roles.function_checkOwnerOrRoles(uint256 roles) internalviewvirtual{
/// @solidity memory-safe-assemblyassembly {
// If the caller is not the stored owner.// Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.ifiszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {
// Compute the role slot.mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, caller())
// Load the stored value, and if the `and` intersection// of the value and `roles` is zero, revert.ifiszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.revert(0x1c, 0x04)
}
}
}
}
/// @dev Throws if the sender does not have any of the `roles`,/// and is not the owner./// Checks for roles first, then lazily checks for ownership.function_checkRolesOrOwner(uint256 roles) internalviewvirtual{
/// @solidity memory-safe-assemblyassembly {
// Compute the role slot.mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, caller())
// Load the stored value, and if the `and` intersection// of the value and `roles` is zero, revert.ifiszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
// If the caller is not the stored owner.// Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.ifiszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.revert(0x1c, 0x04)
}
}
}
}
/// @dev Convenience function to return a `roles` bitmap from an array of `ordinals`./// This is meant for frontends like Etherscan, and is therefore not fully optimized./// Not recommended to be called on-chain./// Made internal to conserve bytecode. Wrap it in a public function if needed.function_rolesFromOrdinals(uint8[] memory ordinals) internalpurereturns (uint256 roles) {
/// @solidity memory-safe-assemblyassembly {
for { let i :=shl(5, mload(ordinals)) } i { i :=sub(i, 0x20) } {
// We don't need to mask the values of `ordinals`, as Solidity// cleans dirty upper bits when storing variables into memory.
roles :=or(shl(mload(add(ordinals, i)), 1), roles)
}
}
}
/// @dev Convenience function to return an array of `ordinals` from the `roles` bitmap./// This is meant for frontends like Etherscan, and is therefore not fully optimized./// Not recommended to be called on-chain./// Made internal to conserve bytecode. Wrap it in a public function if needed.function_ordinalsFromRoles(uint256 roles) internalpurereturns (uint8[] memory ordinals) {
/// @solidity memory-safe-assemblyassembly {
// Grab the pointer to the free memory.
ordinals :=mload(0x40)
let ptr :=add(ordinals, 0x20)
let o :=0// The absence of lookup tables, De Bruijn, etc., here is intentional for// smaller bytecode, as this function is not meant to be called on-chain.for { let t := roles } 1 {} {
mstore(ptr, o)
// `shr` 5 is equivalent to multiplying by 0x20.// Push back into the ordinals array if the bit is set.
ptr :=add(ptr, shl(5, and(t, 1)))
o :=add(o, 1)
t :=shr(o, roles)
ifiszero(t) { break }
}
// Store the length of `ordinals`.mstore(ordinals, shr(5, sub(ptr, add(ordinals, 0x20))))
// Allocate the memory.mstore(0x40, ptr)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* PUBLIC UPDATE FUNCTIONS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Allows the owner to grant `user` `roles`./// If the `user` already has a role, then it will be an no-op for the role.functiongrantRoles(address user, uint256 roles) publicpayablevirtualonlyOwner{
_grantRoles(user, roles);
}
/// @dev Allows the owner to remove `user` `roles`./// If the `user` does not have a role, then it will be an no-op for the role.functionrevokeRoles(address user, uint256 roles) publicpayablevirtualonlyOwner{
_removeRoles(user, roles);
}
/// @dev Allow the caller to remove their own roles./// If the caller does not have a role, then it will be an no-op for the role.functionrenounceRoles(uint256 roles) publicpayablevirtual{
_removeRoles(msg.sender, roles);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* PUBLIC READ FUNCTIONS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Returns the roles of `user`.functionrolesOf(address user) publicviewvirtualreturns (uint256 roles) {
/// @solidity memory-safe-assemblyassembly {
// Compute the role slot.mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
// Load the stored value.
roles :=sload(keccak256(0x0c, 0x20))
}
}
/// @dev Returns whether `user` has any of `roles`.functionhasAnyRole(address user, uint256 roles) publicviewvirtualreturns (bool) {
return rolesOf(user) & roles !=0;
}
/// @dev Returns whether `user` has all of `roles`.functionhasAllRoles(address user, uint256 roles) publicviewvirtualreturns (bool) {
return rolesOf(user) & roles == roles;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* MODIFIERS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*//// @dev Marks a function as only callable by an account with `roles`.modifieronlyRoles(uint256 roles) virtual{
_checkRoles(roles);
_;
}
/// @dev Marks a function as only callable by the owner or by an account/// with `roles`. Checks for ownership first, then lazily checks for roles.modifieronlyOwnerOrRoles(uint256 roles) virtual{
_checkOwnerOrRoles(roles);
_;
}
/// @dev Marks a function as only callable by an account with `roles`/// or the owner. Checks for roles first, then lazily checks for ownership.modifieronlyRolesOrOwner(uint256 roles) virtual{
_checkRolesOrOwner(roles);
_;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*//* ROLE CONSTANTS *//*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/// IYKYKuint256internalconstant _ROLE_0 =1<<0;
uint256internalconstant _ROLE_1 =1<<1;
uint256internalconstant _ROLE_2 =1<<2;
uint256internalconstant _ROLE_3 =1<<3;
uint256internalconstant _ROLE_4 =1<<4;
uint256internalconstant _ROLE_5 =1<<5;
uint256internalconstant _ROLE_6 =1<<6;
uint256internalconstant _ROLE_7 =1<<7;
uint256internalconstant _ROLE_8 =1<<8;
uint256internalconstant _ROLE_9 =1<<9;
uint256internalconstant _ROLE_10 =1<<10;
uint256internalconstant _ROLE_11 =1<<11;
uint256internalconstant _ROLE_12 =1<<12;
uint256internalconstant _ROLE_13 =1<<13;
uint256internalconstant _ROLE_14 =1<<14;
uint256internalconstant _ROLE_15 =1<<15;
uint256internalconstant _ROLE_16 =1<<16;
uint256internalconstant _ROLE_17 =1<<17;
uint256internalconstant _ROLE_18 =1<<18;
uint256internalconstant _ROLE_19 =1<<19;
uint256internalconstant _ROLE_20 =1<<20;
uint256internalconstant _ROLE_21 =1<<21;
uint256internalconstant _ROLE_22 =1<<22;
uint256internalconstant _ROLE_23 =1<<23;
uint256internalconstant _ROLE_24 =1<<24;
uint256internalconstant _ROLE_25 =1<<25;
uint256internalconstant _ROLE_26 =1<<26;
uint256internalconstant _ROLE_27 =1<<27;
uint256internalconstant _ROLE_28 =1<<28;
uint256internalconstant _ROLE_29 =1<<29;
uint256internalconstant _ROLE_30 =1<<30;
uint256internalconstant _ROLE_31 =1<<31;
uint256internalconstant _ROLE_32 =1<<32;
uint256internalconstant _ROLE_33 =1<<33;
uint256internalconstant _ROLE_34 =1<<34;
uint256internalconstant _ROLE_35 =1<<35;
uint256internalconstant _ROLE_36 =1<<36;
uint256internalconstant _ROLE_37 =1<<37;
uint256internalconstant _ROLE_38 =1<<38;
uint256internalconstant _ROLE_39 =1<<39;
uint256internalconstant _ROLE_40 =1<<40;
uint256internalconstant _ROLE_41 =1<<41;
uint256internalconstant _ROLE_42 =1<<42;
uint256internalconstant _ROLE_43 =1<<43;
uint256internalconstant _ROLE_44 =1<<44;
uint256internalconstant _ROLE_45 =1<<45;
uint256internalconstant _ROLE_46 =1<<46;
uint256internalconstant _ROLE_47 =1<<47;
uint256internalconstant _ROLE_48 =1<<48;
uint256internalconstant _ROLE_49 =1<<49;
uint256internalconstant _ROLE_50 =1<<50;
uint256internalconstant _ROLE_51 =1<<51;
uint256internalconstant _ROLE_52 =1<<52;
uint256internalconstant _ROLE_53 =1<<53;
uint256internalconstant _ROLE_54 =1<<54;
uint256internalconstant _ROLE_55 =1<<55;
uint256internalconstant _ROLE_56 =1<<56;
uint256internalconstant _ROLE_57 =1<<57;
uint256internalconstant _ROLE_58 =1<<58;
uint256internalconstant _ROLE_59 =1<<59;
uint256internalconstant _ROLE_60 =1<<60;
uint256internalconstant _ROLE_61 =1<<61;
uint256internalconstant _ROLE_62 =1<<62;
uint256internalconstant _ROLE_63 =1<<63;
uint256internalconstant _ROLE_64 =1<<64;
uint256internalconstant _ROLE_65 =1<<65;
uint256internalconstant _ROLE_66 =1<<66;
uint256internalconstant _ROLE_67 =1<<67;
uint256internalconstant _ROLE_68 =1<<68;
uint256internalconstant _ROLE_69 =1<<69;
uint256internalconstant _ROLE_70 =1<<70;
uint256internalconstant _ROLE_71 =1<<71;
uint256internalconstant _ROLE_72 =1<<72;
uint256internalconstant _ROLE_73 =1<<73;
uint256internalconstant _ROLE_74 =1<<74;
uint256internalconstant _ROLE_75 =1<<75;
uint256internalconstant _ROLE_76 =1<<76;
uint256internalconstant _ROLE_77 =1<<77;
uint256internalconstant _ROLE_78 =1<<78;
uint256internalconstant _ROLE_79 =1<<79;
uint256internalconstant _ROLE_80 =1<<80;
uint256internalconstant _ROLE_81 =1<<81;
uint256internalconstant _ROLE_82 =1<<82;
uint256internalconstant _ROLE_83 =1<<83;
uint256internalconstant _ROLE_84 =1<<84;
uint256internalconstant _ROLE_85 =1<<85;
uint256internalconstant _ROLE_86 =1<<86;
uint256internalconstant _ROLE_87 =1<<87;
uint256internalconstant _ROLE_88 =1<<88;
uint256internalconstant _ROLE_89 =1<<89;
uint256internalconstant _ROLE_90 =1<<90;
uint256internalconstant _ROLE_91 =1<<91;
uint256internalconstant _ROLE_92 =1<<92;
uint256internalconstant _ROLE_93 =1<<93;
uint256internalconstant _ROLE_94 =1<<94;
uint256internalconstant _ROLE_95 =1<<95;
uint256internalconstant _ROLE_96 =1<<96;
uint256internalconstant _ROLE_97 =1<<97;
uint256internalconstant _ROLE_98 =1<<98;
uint256internalconstant _ROLE_99 =1<<99;
uint256internalconstant _ROLE_100 =1<<100;
uint256internalconstant _ROLE_101 =1<<101;
uint256internalconstant _ROLE_102 =1<<102;
uint256internalconstant _ROLE_103 =1<<103;
uint256internalconstant _ROLE_104 =1<<104;
uint256internalconstant _ROLE_105 =1<<105;
uint256internalconstant _ROLE_106 =1<<106;
uint256internalconstant _ROLE_107 =1<<107;
uint256internalconstant _ROLE_108 =1<<108;
uint256internalconstant _ROLE_109 =1<<109;
uint256internalconstant _ROLE_110 =1<<110;
uint256internalconstant _ROLE_111 =1<<111;
uint256internalconstant _ROLE_112 =1<<112;
uint256internalconstant _ROLE_113 =1<<113;
uint256internalconstant _ROLE_114 =1<<114;
uint256internalconstant _ROLE_115 =1<<115;
uint256internalconstant _ROLE_116 =1<<116;
uint256internalconstant _ROLE_117 =1<<117;
uint256internalconstant _ROLE_118 =1<<118;
uint256internalconstant _ROLE_119 =1<<119;
uint256internalconstant _ROLE_120 =1<<120;
uint256internalconstant _ROLE_121 =1<<121;
uint256internalconstant _ROLE_122 =1<<122;
uint256internalconstant _ROLE_123 =1<<123;
uint256internalconstant _ROLE_124 =1<<124;
uint256internalconstant _ROLE_125 =1<<125;
uint256internalconstant _ROLE_126 =1<<126;
uint256internalconstant _ROLE_127 =1<<127;
uint256internalconstant _ROLE_128 =1<<128;
uint256internalconstant _ROLE_129 =1<<129;
uint256internalconstant _ROLE_130 =1<<130;
uint256internalconstant _ROLE_131 =1<<131;
uint256internalconstant _ROLE_132 =1<<132;
uint256internalconstant _ROLE_133 =1<<133;
uint256internalconstant _ROLE_134 =1<<134;
uint256internalconstant _ROLE_135 =1<<135;
uint256internalconstant _ROLE_136 =1<<136;
uint256internalconstant _ROLE_137 =1<<137;
uint256internalconstant _ROLE_138 =1<<138;
uint256internalconstant _ROLE_139 =1<<139;
uint256internalconstant _ROLE_140 =1<<140;
uint256internalconstant _ROLE_141 =1<<141;
uint256internalconstant _ROLE_142 =1<<142;
uint256internalconstant _ROLE_143 =1<<143;
uint256internalconstant _ROLE_144 =1<<144;
uint256internalconstant _ROLE_145 =1<<145;
uint256internalconstant _ROLE_146 =1<<146;
uint256internalconstant _ROLE_147 =1<<147;
uint256internalconstant _ROLE_148 =1<<148;
uint256internalconstant _ROLE_149 =1<<149;
uint256internalconstant _ROLE_150 =1<<150;
uint256internalconstant _ROLE_151 =1<<151;
uint256internalconstant _ROLE_152 =1<<152;
uint256internalconstant _ROLE_153 =1<<153;
uint256internalconstant _ROLE_154 =1<<154;
uint256internalconstant _ROLE_155 =1<<155;
uint256internalconstant _ROLE_156 =1<<156;
uint256internalconstant _ROLE_157 =1<<157;
uint256internalconstant _ROLE_158 =1<<158;
uint256internalconstant _ROLE_159 =1<<159;
uint256internalconstant _ROLE_160 =1<<160;
uint256internalconstant _ROLE_161 =1<<161;
uint256internalconstant _ROLE_162 =1<<162;
uint256internalconstant _ROLE_163 =1<<163;
uint256internalconstant _ROLE_164 =1<<164;
uint256internalconstant _ROLE_165 =1<<165;
uint256internalconstant _ROLE_166 =1<<166;
uint256internalconstant _ROLE_167 =1<<167;
uint256internalconstant _ROLE_168 =1<<168;
uint256internalconstant _ROLE_169 =1<<169;
uint256internalconstant _ROLE_170 =1<<170;
uint256internalconstant _ROLE_171 =1<<171;
uint256internalconstant _ROLE_172 =1<<172;
uint256internalconstant _ROLE_173 =1<<173;
uint256internalconstant _ROLE_174 =1<<174;
uint256internalconstant _ROLE_175 =1<<175;
uint256internalconstant _ROLE_176 =1<<176;
uint256internalconstant _ROLE_177 =1<<177;
uint256internalconstant _ROLE_178 =1<<178;
uint256internalconstant _ROLE_179 =1<<179;
uint256internalconstant _ROLE_180 =1<<180;
uint256internalconstant _ROLE_181 =1<<181;
uint256internalconstant _ROLE_182 =1<<182;
uint256internalconstant _ROLE_183 =1<<183;
uint256internalconstant _ROLE_184 =1<<184;
uint256internalconstant _ROLE_185 =1<<185;
uint256internalconstant _ROLE_186 =1<<186;
uint256internalconstant _ROLE_187 =1<<187;
uint256internalconstant _ROLE_188 =1<<188;
uint256internalconstant _ROLE_189 =1<<189;
uint256internalconstant _ROLE_190 =1<<190;
uint256internalconstant _ROLE_191 =1<<191;
uint256internalconstant _ROLE_192 =1<<192;
uint256internalconstant _ROLE_193 =1<<193;
uint256internalconstant _ROLE_194 =1<<194;
uint256internalconstant _ROLE_195 =1<<195;
uint256internalconstant _ROLE_196 =1<<196;
uint256internalconstant _ROLE_197 =1<<197;
uint256internalconstant _ROLE_198 =1<<198;
uint256internalconstant _ROLE_199 =1<<199;
uint256internalconstant _ROLE_200 =1<<200;
uint256internalconstant _ROLE_201 =1<<201;
uint256internalconstant _ROLE_202 =1<<202;
uint256internalconstant _ROLE_203 =1<<203;
uint256internalconstant _ROLE_204 =1<<204;
uint256internalconstant _ROLE_205 =1<<205;
uint256internalconstant _ROLE_206 =1<<206;
uint256internalconstant _ROLE_207 =1<<207;
uint256internalconstant _ROLE_208 =1<<208;
uint256internalconstant _ROLE_209 =1<<209;
uint256internalconstant _ROLE_210 =1<<210;
uint256internalconstant _ROLE_211 =1<<211;
uint256internalconstant _ROLE_212 =1<<212;
uint256internalconstant _ROLE_213 =1<<213;
uint256internalconstant _ROLE_214 =1<<214;
uint256internalconstant _ROLE_215 =1<<215;
uint256internalconstant _ROLE_216 =1<<216;
uint256internalconstant _ROLE_217 =1<<217;
uint256internalconstant _ROLE_218 =1<<218;
uint256internalconstant _ROLE_219 =1<<219;
uint256internalconstant _ROLE_220 =1<<220;
uint256internalconstant _ROLE_221 =1<<221;
uint256internalconstant _ROLE_222 =1<<222;
uint256internalconstant _ROLE_223 =1<<223;
uint256internalconstant _ROLE_224 =1<<224;
uint256internalconstant _ROLE_225 =1<<225;
uint256internalconstant _ROLE_226 =1<<226;
uint256internalconstant _ROLE_227 =1<<227;
uint256internalconstant _ROLE_228 =1<<228;
uint256internalconstant _ROLE_229 =1<<229;
uint256internalconstant _ROLE_230 =1<<230;
uint256internalconstant _ROLE_231 =1<<231;
uint256internalconstant _ROLE_232 =1<<232;
uint256internalconstant _ROLE_233 =1<<233;
uint256internalconstant _ROLE_234 =1<<234;
uint256internalconstant _ROLE_235 =1<<235;
uint256internalconstant _ROLE_236 =1<<236;
uint256internalconstant _ROLE_237 =1<<237;
uint256internalconstant _ROLE_238 =1<<238;
uint256internalconstant _ROLE_239 =1<<239;
uint256internalconstant _ROLE_240 =1<<240;
uint256internalconstant _ROLE_241 =1<<241;
uint256internalconstant _ROLE_242 =1<<242;
uint256internalconstant _ROLE_243 =1<<243;
uint256internalconstant _ROLE_244 =1<<244;
uint256internalconstant _ROLE_245 =1<<245;
uint256internalconstant _ROLE_246 =1<<246;
uint256internalconstant _ROLE_247 =1<<247;
uint256internalconstant _ROLE_248 =1<<248;
uint256internalconstant _ROLE_249 =1<<249;
uint256internalconstant _ROLE_250 =1<<250;
uint256internalconstant _ROLE_251 =1<<251;
uint256internalconstant _ROLE_252 =1<<252;
uint256internalconstant _ROLE_253 =1<<253;
uint256internalconstant _ROLE_254 =1<<254;
uint256internalconstant _ROLE_255 =1<<255;
}