burnTokensOf
Contract: JBController
Interface: IJBController
- Step by step
- Code
- Errors
- Events
- Bug bounty
Burns a token holder's supply.
Only a token's holder, a designated operator, or a project's terminal can burn it.
Definition
function burnTokensOf(
address _holder,
uint256 _projectId,
uint256 _tokenCount,
string calldata _memo,
bool _preferClaimedTokens
)
external
virtual
override
nonReentrant
requirePermissionAllowingOverride(
_holder,
_projectId,
JBOperations.BURN,
directory.isTerminalDelegateOf(_projectId, msg.sender)
) { ... }
- Arguments:
_holder
is the account that is having its tokens burned._projectId
is the ID of the project to which the tokens being burned belong._tokenCount
is the number of tokens to burn._memo
is a memo to pass along to the emitted event._preferClaimedTokens
is flag indicating whether a project's attached token contract should be burned first if they have been issued.
- Through the
requirePermissionAllowingOverride
modifier, the function is only accessible by the project's owner, from an operator that has been given theJBOperations.BURN
permission by the project owner for the provided_projectId
, or from one of the project's terminal's delegates. - The function can be overriden by inheriting contracts.
- The function overrides a function definition from the
IJBController
interface. - The function doesn't return anything.
Body
-
Make sure there is a specified number of tokens to burn.
// There should be tokens to burn
if (_tokenCount == 0) revert NO_BURNABLE_TOKENS(); -
Get a reference to the current funding cycle for the project.
// Get a reference to the project's current funding cycle.
JBFundingCycle memory _fundingCycle = fundingCycleStore.currentOf(_projectId);Internal references:
External references:
-
Make sure the current funding cycle for the project hasn't paused burning if the request is not coming from one of the project's terminals. If the request is coming from a terminal, allow burning regardless of the pause state because it could be a sub-routine of another operation such as redemption.
// If the message sender is a terminal, the current funding cycle must not be paused.
if (
_fundingCycle.burnPaused() &&
!directory.isTerminalOf(_projectId, IJBPaymentTerminal(msg.sender))
) revert BURN_PAUSED_AND_SENDER_NOT_VALID_TERMINAL_DELEGATE();Internal references:
Library references:
JBFundingCycleMetadataResolver
.burnPaused(...)
External references:
-
Update the token tracker so that the correct amount of reserved tokens are still mintable after the burn.
// Update the token tracker so that reserved tokens will still be correctly mintable.
_processedTokenTrackerOf[_projectId] =
_processedTokenTrackerOf[_projectId] -
SafeCast.toInt256(_tokenCount);Library references:
SafeCast
.toInt256(...)
Internal references:
-
Burn the tokens.
// Burn the tokens.
tokenStore.burnFrom(_holder, _projectId, _tokenCount, _preferClaimedTokens);Internal references:
External references:
-
Emit a
BurnTokens
event with the relevant parameters.emit BurnTokens(_holder, _projectId, _tokenCount, _memo, msg.sender);
Event references:
/**
@notice
Burns a token holder's supply.
@dev
Only a token's holder, a designated operator, or a project's terminal can burn it.
@param _holder The account that is having its tokens burned.
@param _projectId The ID of the project to which the tokens being burned belong.
@param _tokenCount The number of tokens to burn.
@param _memo A memo to pass along to the emitted event.
@param _preferClaimedTokens A flag indicating whether a project's attached token contract should be burned first if they have been issued.
*/
function burnTokensOf(
address _holder,
uint256 _projectId,
uint256 _tokenCount,
string calldata _memo,
bool _preferClaimedTokens
)
external
virtual
override
requirePermissionAllowingOverride(
_holder,
_projectId,
JBOperations.BURN,
directory.isTerminalOf(_projectId, IJBPaymentTerminal(msg.sender))
)
{
// There should be tokens to burn
if (_tokenCount == 0) revert NO_BURNABLE_TOKENS();
// Get a reference to the project's current funding cycle.
JBFundingCycle memory _fundingCycle = fundingCycleStore.currentOf(_projectId);
// If the message sender is a terminal, the current funding cycle must not be paused.
if (
_fundingCycle.burnPaused() &&
!directory.isTerminalOf(_projectId, IJBPaymentTerminal(msg.sender))
) revert BURN_PAUSED_AND_SENDER_NOT_VALID_TERMINAL_DELEGATE();
// Update the token tracker so that reserved tokens will still be correctly mintable.
_processedTokenTrackerOf[_projectId] =
_processedTokenTrackerOf[_projectId] -
SafeCast.toInt256(_tokenCount);
// Burn the tokens.
tokenStore.burnFrom(_holder, _projectId, _tokenCount, _preferClaimedTokens);
emit BurnTokens(_holder, _projectId, _tokenCount, _memo, msg.sender);
}
String | Description |
---|---|
NO_BURNABLE_TOKENS | Thrown if no tokens are being burned. |
BURN_PAUSED_AND_SENDER_NOT_VALID_TERMINAL_DELEGATE | Thrown if the request is not being made by a payment terminal, and the project's current funding cycle has paused burning. |
Name | Data |
---|---|
BurnTokens |
|
Category | Description | Reward |
---|---|---|
Optimization | Help make this operation more efficient. | 0.5ETH |
Low severity | Identify a vulnerability in this operation that could lead to an inconvenience for a user of the protocol or for a protocol developer. | 1ETH |
High severity | Identify a vulnerability in this operation that could lead to data corruption or loss of funds. | 5+ETH |