Transient Labs Sol Tools

Inheritable contracts that can be used for a variety of purposes. This is largely inspired by the work done by OpenZeppelin.

Usage

You should have no trouble inheriting from this library if you install with foundry.

When cloning, you must use either make remove && make install or make update to install/update the required modules, such as forge-std or OpenZeppelin contracts.

We use OpenZeppelin contracts version 5.0.1 in this codebase.

Testing

You should run the test suites in the Makefile.

This loops through the following solidity versions:

  • 0.8.20
  • 0.8.21
  • 0.8.22

Disclaimer

This codebase is provided on an "as is" and "as available" basis.

We do not give any warranties and will not be liable for any loss incurred through any use of this codebase.

License

This code is copyright Transient Labs, Inc 2023 and is licensed under the MIT license.

Contents

OwnableAccessControl

Git Source

Inherits: Ownable

Author: transientlabs.xyz

Single owner, flexible access control mechanics

Can easily be extended by inheriting and applying additional roles

By default, only the owner can grant roles but by inheriting, but you may allow other roles to grant roles by using the internal helper.

State Variables

_c

uint256 private _c;

_roleStatus

mapping(uint256 => mapping(bytes32 => mapping(address => bool))) private _roleStatus;

_roleMembers

mapping(uint256 => mapping(bytes32 => EnumerableSet.AddressSet)) private _roleMembers;

Functions

onlyRole

modifier onlyRole(bytes32 role);

onlyRoleOrOwner

modifier onlyRoleOrOwner(bytes32 role);

constructor

constructor() Ownable(msg.sender);

revokeAllRoles

Function to revoke all roles currently present

Increments the _c variables

Requires owner privileges

function revokeAllRoles() external onlyOwner;

renounceRole

Function to renounce role

function renounceRole(bytes32 role) external;

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts

setRole

Function to grant/revoke a role to an address

Requires owner to call this function but this may be further extended using the internal helper function in inheriting contracts

function setRole(bytes32 role, address[] memory roleMembers, bool status) external onlyOwner;

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts
roleMembersaddress[]List of addresses that should have roles attached to them based on status
statusboolBool whether to remove or add roleMembers to the role

hasRole

Function to see if an address is the owner

function hasRole(bytes32 role, address potentialRoleMember) public view returns (bool);

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts
potentialRoleMemberaddressAddress to check for role membership

getRoleMembers

Function to get role members

function getRoleMembers(bytes32 role) public view returns (address[] memory);

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts

_setRole

Helper function to set addresses for a role

function _setRole(bytes32 role, address[] memory roleMembers, bool status) internal;

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts
roleMembersaddress[]List of addresses that should have roles attached to them based on status
statusboolBool whether to remove or add roleMembers to the role

Events

RoleChange

event RoleChange(address indexed from, address indexed user, bool indexed approved, bytes32 role);

AllRolesRevoked

event AllRolesRevoked(address indexed from);

Errors

NotSpecifiedRole

Does not have specified role

error NotSpecifiedRole(bytes32 role);

NotRoleOrOwner

Is not specified role or owner

error NotRoleOrOwner(bytes32 role);

Contents

IChainalysisSanctionsOracle

Git Source

Functions

isSanctioned

function isSanctioned(address addr) external view returns (bool);

IWETH

Git Source

Inherits: IERC20

Functions

deposit

function deposit() external payable;

RoyaltyPayoutHelper

Git Source

Inherits: TransferHelper, SanctionsCompliance

Author: transientlabs.xyz

Abstract contract to help payout royalties using the Royalty Registry

Does not manage updating the sanctions oracle and expects the child contract to implement

State Variables

weth

address public weth;

royaltyEngine

IRoyaltyEngineV1 public royaltyEngine;

Functions

constructor

constructor(address sanctionsOracle, address wethAddress, address royaltyEngineAddress)
    SanctionsCompliance(sanctionsOracle);

Parameters

NameTypeDescription
sanctionsOracleaddress- the init sanctions oracle
wethAddressaddress- the init weth address
royaltyEngineAddressaddress- the init royalty engine address

_setWethAddress

Function to update the WETH address

Care should be taken to ensure proper access control for this function

function _setWethAddress(address wethAddress) internal;

Parameters

NameTypeDescription
wethAddressaddressThe new WETH token address

_setRoyaltyEngineAddress

Function to update the royalty engine address

Care should be taken to ensure proper access control for this function

function _setRoyaltyEngineAddress(address royaltyEngineAddress) internal;

Parameters

NameTypeDescription
royaltyEngineAddressaddressThe new royalty engine address

_payoutRoyalties

Function to payout royalties from the contract balance based on sale price

if the call to the royalty engine reverts or if the return values are invalid, no payments are made

if the sum of the royalty payouts is greater than the salePrice, the loop exits early for gas savings (this shouldn't happen in reality)

if this is used in a call where tokens should be transferred from a sender, it is advisable to first transfer the required amount to the contract and then call this function, as it will save on gas

function _payoutRoyalties(address token, uint256 tokenId, address currency, uint256 salePrice)
    internal
    returns (uint256 remainingSale);

Parameters

NameTypeDescription
tokenaddressThe contract address for the token
tokenIduint256The token id
currencyaddressThe address of the currency to send to recipients (null address == ETH)
salePriceuint256The sale price for the token

Returns

NameTypeDescription
remainingSaleuint256The amount left over in the sale after paying out royalties

SanctionsCompliance

Git Source

Author: transientlabs.xyz

Abstract contract to comply with U.S. sanctioned addresses

Uses the Chainalysis Sanctions Oracle for checking sanctions

State Variables

oracle

IChainalysisSanctionsOracle public oracle;

Functions

constructor

constructor(address initOracle);

_updateSanctionsOracle

Internal function to change the sanctions oracle

function _updateSanctionsOracle(address newOracle) internal;

Parameters

NameTypeDescription
newOracleaddressThe new sanctions oracle address

_isSanctioned

Internal function to check the sanctions oracle for an address

Disable sanction checking by setting the oracle to the zero address

function _isSanctioned(address sender, bool shouldRevertIfSanctioned) internal view returns (bool isSanctioned);

Parameters

NameTypeDescription
senderaddressThe address that is trying to send money
shouldRevertIfSanctionedboolA flag indicating if the call should revert if the sender is sanctioned. Set to false if wanting to get a result.

Returns

NameTypeDescription
isSanctionedboolBoolean indicating if the sender is sanctioned

Events

SanctionsOracleUpdated

event SanctionsOracleUpdated(address indexed prevOracle, address indexed newOracle);

Errors

SanctionedAddress

Sanctioned address by OFAC

error SanctionedAddress();

TransferHelper

Git Source

Author: transientlabs.xyz

Abstract contract that has helper function for sending ETH and ERC20's safely

Functions

_safeTransferETH

Function to force transfer ETH, defaulting to forwarding 100k gas

On failure to send the ETH, the ETH is converted to WETH and sent

Care should be taken to always pass the proper WETH address that adheres to IWETH

function _safeTransferETH(address recipient, uint256 amount, address weth) internal;

Parameters

NameTypeDescription
recipientaddressThe recipient of the ETH
amountuint256The amount of ETH to send
wethaddressThe WETH token address

_safeTransferETH

Function to force transfer ETH, with a gas limit

On failure to send the ETH, the ETH is converted to WETH and sent

Care should be taken to always pass the proper WETH address that adheres to IWETH

If the amount is zero, the function returns in order to save gas

function _safeTransferETH(address recipient, uint256 amount, address weth, uint256 gasLimit) internal;

Parameters

NameTypeDescription
recipientaddressThe recipient of the ETH
amountuint256The amount of ETH to send
wethaddressThe WETH token address
gasLimituint256The gas to forward

_safeTransferERC20

Function to safely transfer ERC-20 tokens from the contract, without checking for token tax

Does not check if the sender has enough balance as that is handled by the token contract

Does not check for token tax as that could lock up funds in the contract

Reverts on failure to transfer

If the amount is zero, the function returns in order to save gas

function _safeTransferERC20(address recipient, address currency, uint256 amount) internal;

Parameters

NameTypeDescription
recipientaddressThe recipient of the ERC-20 token
currencyaddressThe address of the ERC-20 token
amountuint256The amount of ERC-20 to send

_safeTransferFromERC20

Function to safely transfer ERC-20 tokens from another address to a recipient

Does not check if the sender has enough balance or allowance for this contract as that is handled by the token contract

Reverts on failure to transfer

Reverts if there is a token tax taken out

Returns and doesn't do anything if the sender and recipient are the same address

If the amount is zero, the function returns in order to save gas

function _safeTransferFromERC20(address sender, address recipient, address currency, uint256 amount) internal;

Parameters

NameTypeDescription
senderaddressThe sender of the tokens
recipientaddressThe recipient of the ERC-20 token
currencyaddressThe address of the ERC-20 token
amountuint256The amount of ERC-20 to send

Errors

ETHTransferFailed

ETH transfer failed

error ETHTransferFailed();

InsufficentERC20Transfer

Transferred too few ERC-20 tokens

error InsufficentERC20Transfer();

Contents

EIP2981TL

Git Source

Inherits: IEIP2981, ERC165

Author: transientlabs.xyz

Abstract contract to define a default royalty spec while allowing for specific token overrides

Follows EIP-2981 (https://eips.ethereum.org/EIPS/eip-2981)

State Variables

BASIS

uint256 public constant BASIS = 10_000;

_defaultRecipient

address private _defaultRecipient;

_defaultPercentage

uint256 private _defaultPercentage;

_tokenOverrides

mapping(uint256 => RoyaltySpec) private _tokenOverrides;

Functions

constructor

constructor(address defaultRecipient, uint256 defaultPercentage);

Parameters

NameTypeDescription
defaultRecipientaddressThe default royalty payout address
defaultPercentageuint256The deafult royalty percentage, out of 10,000

_setDefaultRoyaltyInfo

Function to set default royalty info

function _setDefaultRoyaltyInfo(address newRecipient, uint256 newPercentage) internal;

Parameters

NameTypeDescription
newRecipientaddressThe new default royalty payout address
newPercentageuint256The new default royalty percentage, out of 10,000

_overrideTokenRoyaltyInfo

Function to override royalty spec on a specific token

function _overrideTokenRoyaltyInfo(uint256 tokenId, address newRecipient, uint256 newPercentage) internal;

Parameters

NameTypeDescription
tokenIduint256The token id to override royalty for
newRecipientaddressThe new royalty payout address
newPercentageuint256The new royalty percentage, out of 10,000

royaltyInfo

ERC165 bytes to add to interface array - set in parent contract implementing this standard bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a

function royaltyInfo(uint256 tokenId, uint256 salePrice)
    external
    view
    returns (address receiver, uint256 royaltyAmount);

Parameters

NameTypeDescription
tokenIduint256The NFT asset queried for royalty information
salePriceuint256The sale price of the NFT asset specified by tokenId

Returns

NameTypeDescription
receiveraddressAddress of who should be sent the royalty payment
royaltyAmountuint256The royalty payment amount for salePrice

supportsInterface

function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool);

getDefaultRoyaltyRecipientAndPercentage

Query the default royalty receiver and percentage.

function getDefaultRoyaltyRecipientAndPercentage() external view returns (address, uint256);

Returns

NameTypeDescription
<none>addressTuple containing the default royalty recipient and percentage out of 10_000
<none>uint256

Events

DefaultRoyaltyUpdate

Event to emit when the default roylaty is updated

event DefaultRoyaltyUpdate(address indexed sender, address newRecipient, uint256 newPercentage);

TokenRoyaltyOverride

Event to emit when a token royalty is overriden

event TokenRoyaltyOverride(
    address indexed sender, uint256 indexed tokenId, address newRecipient, uint256 newPercentage
);

Errors

ZeroAddressError

error if the recipient is set to address(0)

error ZeroAddressError();

MaxRoyaltyError

error if the royalty percentage is greater than to 100%

error MaxRoyaltyError();

Structs

RoyaltySpec

struct RoyaltySpec {
    address recipient;
    uint256 percentage;
}

IEIP2981

Git Source

Interface for the NFT Royalty Standard

Functions

royaltyInfo

ERC165 bytes to add to interface array - set in parent contract implementing this standard bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a

Called with the sale price to determine how much royalty

function royaltyInfo(uint256 tokenId, uint256 salePrice)
    external
    view
    returns (address receiver, uint256 royaltyAmount);

Parameters

NameTypeDescription
tokenIduint256The NFT asset queried for royalty information
salePriceuint256The sale price of the NFT asset specified by tokenId

Returns

NameTypeDescription
receiveraddressAddress of who should be sent the royalty payment
royaltyAmountuint256The royalty payment amount for salePrice

Contents

Contents

OwnableAccessControlUpgradeable

Git Source

Inherits: OwnableUpgradeable

Author: transientlabs.xyz

Single owner, flexible access control mechanics

Can easily be extended by inheriting and applying additional roles

By default, only the owner can grant roles but by inheriting, but you may allow other roles to grant roles by using the internal helper.

State Variables

OwnableAccessControlStorageLocation

bytes32 private constant OwnableAccessControlStorageLocation =
    0x0d0469b3d32e63681b9fc586a5627ad5e70b3d1ad20f31767e4b6c4141c7e300;

Functions

_getOwnableAccessControlStorage

function _getOwnableAccessControlStorage() private pure returns (OwnableAccessControlStorage storage $);

onlyRole

modifier onlyRole(bytes32 role);

onlyRoleOrOwner

modifier onlyRoleOrOwner(bytes32 role);

__OwnableAccessControl_init

function __OwnableAccessControl_init(address initOwner) internal onlyInitializing;

Parameters

NameTypeDescription
initOwneraddressThe address of the initial owner

__OwnableAccessControl_init_unchained

function __OwnableAccessControl_init_unchained() internal onlyInitializing;

revokeAllRoles

Function to revoke all roles currently present

Increments the _c variables

Requires owner privileges

function revokeAllRoles() external onlyOwner;

renounceRole

Function to renounce role

function renounceRole(bytes32 role) external;

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts

setRole

Function to grant/revoke a role to an address

Requires owner to call this function but this may be further extended using the internal helper function in inheriting contracts

function setRole(bytes32 role, address[] memory roleMembers, bool status) external onlyOwner;

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts
roleMembersaddress[]List of addresses that should have roles attached to them based on status
statusboolBool whether to remove or add roleMembers to the role

hasRole

Function to see if an address is the owner

function hasRole(bytes32 role, address potentialRoleMember) public view returns (bool);

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts
potentialRoleMemberaddressAddress to check for role membership

getRoleMembers

Function to get role members

function getRoleMembers(bytes32 role) public view returns (address[] memory);

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts

_setRole

Helper function to set addresses for a role

function _setRole(bytes32 role, address[] memory roleMembers, bool status) internal;

Parameters

NameTypeDescription
rolebytes32Bytes32 role created in inheriting contracts
roleMembersaddress[]List of addresses that should have roles attached to them based on status
statusboolBool whether to remove or add roleMembers to the role

Events

RoleChange

event RoleChange(address indexed from, address indexed user, bool indexed approved, bytes32 role);

AllRolesRevoked

event AllRolesRevoked(address indexed from);

Errors

NotSpecifiedRole

Does not have specified role

error NotSpecifiedRole(bytes32 role);

NotRoleOrOwner

Is not specified role or owner

error NotRoleOrOwner(bytes32 role);

Structs

OwnableAccessControlStorage

struct OwnableAccessControlStorage {
    uint256 c;
    mapping(uint256 => mapping(bytes32 => mapping(address => bool))) roleStatus;
    mapping(uint256 => mapping(bytes32 => EnumerableSet.AddressSet)) roleMembers;
}

Contents

RoyaltyPayoutHelperUpgradeable

Git Source

Inherits: SanctionsComplianceUpgradeable, TransferHelper

Author: transientlabs.xyz

Abstract contract to help payout royalties using the Royalty Registry

Does not manage updating the sanctions oracle and expects the child contract to implement

State Variables

RoyaltyPayoutHelperStorageLocation

bytes32 private constant RoyaltyPayoutHelperStorageLocation =
    0x9ab1d1ca9bfa2c669468b724939724262b3f2887db3df18c90168701d6422700;

Functions

_getRoyaltyPayoutHelperStorage

function _getRoyaltyPayoutHelperStorage() private pure returns (RoyaltyPayoutHelperStorage storage $);

__RoyaltyPayoutHelper_init

Function to initialize the contract

function __RoyaltyPayoutHelper_init(address sanctionsOracle, address wethAddress, address royaltyEngineAddress)
    internal
    onlyInitializing;

Parameters

NameTypeDescription
sanctionsOracleaddress- the init sanctions oracle
wethAddressaddress- the init weth address
royaltyEngineAddressaddress- the init royalty engine address

__RoyaltyPayoutHelper_init_unchained

unchained function to initialize the contract

function __RoyaltyPayoutHelper_init_unchained(address wethAddress, address royaltyEngineAddress)
    internal
    onlyInitializing;

Parameters

NameTypeDescription
wethAddressaddress- the init weth address
royaltyEngineAddressaddress- the init royalty engine address

_setWethAddress

Function to update the WETH address

Care should be taken to ensure proper access control for this function

function _setWethAddress(address wethAddress) internal;

Parameters

NameTypeDescription
wethAddressaddressThe new WETH token address

_setRoyaltyEngineAddress

Function to update the royalty engine address

Care should be taken to ensure proper access control for this function

function _setRoyaltyEngineAddress(address royaltyEngineAddress) internal;

Parameters

NameTypeDescription
royaltyEngineAddressaddressThe new royalty engine address

_payoutRoyalties

Function to payout royalties from the contract balance based on sale price

if the call to the royalty engine reverts or if the return values are invalid, no payments are made

if the sum of the royalty payouts is greater than the salePrice, the loop exits early for gas savings (this shouldn't happen in reality)

if this is used in a call where tokens should be transferred from a sender, it is advisable to first transfer the required amount to the contract and then call this function, as it will save on gas

function _payoutRoyalties(address token, uint256 tokenId, address currency, uint256 salePrice)
    internal
    returns (uint256 remainingSale);

Parameters

NameTypeDescription
tokenaddressThe contract address for the token
tokenIduint256The token id
currencyaddressThe address of the currency to send to recipients (null address == ETH)
salePriceuint256The sale price for the token

Returns

NameTypeDescription
remainingSaleuint256The amount left over in the sale after paying out royalties

weth

Function to get the current WETH address

function weth() public view returns (address);

royaltyEngine

Function to get the royalty registry

function royaltyEngine() public view returns (IRoyaltyEngineV1);

Structs

RoyaltyPayoutHelperStorage

struct RoyaltyPayoutHelperStorage {
    address weth;
    IRoyaltyEngineV1 royaltyEngine;
}

SanctionsComplianceUpgradeable

Git Source

Inherits: Initializable

Author: transientlabs.xyz

Abstract contract to comply with U.S. sanctioned addresses

Uses the Chainalysis Sanctions Oracle for checking sanctions

State Variables

SanctionComplianceStorageLocation

bytes32 private constant SanctionComplianceStorageLocation =
    0xd66684c5a7747baca4a45cbf84c01526f3b53186fc4aea64a4c6e2fa4447c700;

Functions

_getSanctionsComplianceStorage

function _getSanctionsComplianceStorage() private pure returns (SanctionComplianceStorage storage $);

__SanctionsCompliance_init

Function to initialize the contract

function __SanctionsCompliance_init(address initOracle) internal onlyInitializing;

Parameters

NameTypeDescription
initOracleaddressThe initial oracle address

__SanctionsCompliance_init_unchained

unchained function to initialize the contract

function __SanctionsCompliance_init_unchained(address initOracle) internal onlyInitializing;

Parameters

NameTypeDescription
initOracleaddressThe initial oracle address

_updateSanctionsOracle

Internal function to change the sanctions oracle

function _updateSanctionsOracle(address newOracle) internal;

Parameters

NameTypeDescription
newOracleaddressThe new sanctions oracle address

_isSanctioned

Internal function to check the sanctions oracle for an address

Disable sanction checking by setting the oracle to the zero address

function _isSanctioned(address sender, bool shouldRevertIfSanctioned) internal view returns (bool isSanctioned);

Parameters

NameTypeDescription
senderaddressThe address that is trying to send money
shouldRevertIfSanctionedboolA flag indicating if the call should revert if the sender is sanctioned. Set to false if wanting to get a result.

Returns

NameTypeDescription
isSanctionedboolBoolean indicating if the sender is sanctioned

oracle

Function to get chainalysis oracle

function oracle() public view returns (IChainalysisSanctionsOracle);

Events

SanctionsOracleUpdated

event SanctionsOracleUpdated(address indexed prevOracle, address indexed newOracle);

Errors

SanctionedAddress

Sanctioned address by OFAC

error SanctionedAddress();

Structs

SanctionComplianceStorage

struct SanctionComplianceStorage {
    IChainalysisSanctionsOracle oracle;
}

Contents

EIP2981TLUpgradeable

Git Source

Inherits: IEIP2981, ERC165Upgradeable

Author: transientlabs.xyz

Abstract contract to define a default royalty spec while allowing for specific token overrides

Follows EIP-2981 (https://eips.ethereum.org/EIPS/eip-2981)

State Variables

EIP2981TLStorageLocation

bytes32 private constant EIP2981TLStorageLocation = 0xe9db8e9b56f2e28e12956850f386d9a4c1e886a4f584b61a10a9d0cacee70700;

BASIS

uint256 public constant BASIS = 10_000;

Functions

_getEIP2981TLStorage

function _getEIP2981TLStorage() private pure returns (EIP2981TLStorage storage $);

__EIP2981TL_init

Function to initialize the contract

function __EIP2981TL_init(address defaultRecipient, uint256 defaultPercentage) internal onlyInitializing;

Parameters

NameTypeDescription
defaultRecipientaddressThe default royalty payout address
defaultPercentageuint256The deafult royalty percentage, out of 10,000

__EIP2981TL_init_unchained

Unchained function to initialize the contract

function __EIP2981TL_init_unchained(address defaultRecipient, uint256 defaultPercentage) internal onlyInitializing;

Parameters

NameTypeDescription
defaultRecipientaddressThe default royalty payout address
defaultPercentageuint256The deafult royalty percentage, out of 10,000

_setDefaultRoyaltyInfo

Function to set default royalty info

function _setDefaultRoyaltyInfo(address newRecipient, uint256 newPercentage) internal;

Parameters

NameTypeDescription
newRecipientaddressThe new default royalty payout address
newPercentageuint256The new default royalty percentage, out of 10,000

_overrideTokenRoyaltyInfo

Function to override royalty spec on a specific token

function _overrideTokenRoyaltyInfo(uint256 tokenId, address newRecipient, uint256 newPercentage) internal;

Parameters

NameTypeDescription
tokenIduint256The token id to override royalty for
newRecipientaddressThe new royalty payout address
newPercentageuint256The new royalty percentage, out of 10,000

royaltyInfo

ERC165 bytes to add to interface array - set in parent contract implementing this standard bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a

function royaltyInfo(uint256 tokenId, uint256 salePrice)
    external
    view
    returns (address receiver, uint256 royaltyAmount);

Parameters

NameTypeDescription
tokenIduint256The NFT asset queried for royalty information
salePriceuint256The sale price of the NFT asset specified by tokenId

Returns

NameTypeDescription
receiveraddressAddress of who should be sent the royalty payment
royaltyAmountuint256The royalty payment amount for salePrice

supportsInterface

function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable) returns (bool);

getDefaultRoyaltyRecipientAndPercentage

Query the default royalty receiver and percentage.

function getDefaultRoyaltyRecipientAndPercentage() external view returns (address, uint256);

Returns

NameTypeDescription
<none>addressTuple containing the default royalty recipient and percentage out of 10_000
<none>uint256

Events

DefaultRoyaltyUpdate

Event to emit when the default roylaty is updated

event DefaultRoyaltyUpdate(address indexed sender, address newRecipient, uint256 newPercentage);

TokenRoyaltyOverride

Event to emit when a token royalty is overriden

event TokenRoyaltyOverride(
    address indexed sender, uint256 indexed tokenId, address newRecipient, uint256 newPercentage
);

Errors

ZeroAddressError

error if the recipient is set to address(0)

error ZeroAddressError();

MaxRoyaltyError

error if the royalty percentage is greater than to 100%

error MaxRoyaltyError();

Structs

RoyaltySpec

struct RoyaltySpec {
    address recipient;
    uint256 percentage;
}

EIP2981TLStorage

struct EIP2981TLStorage {
    address defaultRecipient;
    uint256 defaultPercentage;
    mapping(uint256 => RoyaltySpec) tokenOverrides;
}