burnFrom
Contract: JBTokenStore
Interface: IJBTokenStore
- Step by step
- Code
- Errors
- Events
- Bug bounty
Burns a project's tokens.
Only a project's current controller can burn its tokens.
Definition
function burnFrom(
address _holder,
uint256 _projectId,
uint256 _amount,
bool _preferClaimedTokens
) external override onlyController(_projectId) { ... }
- Arguments:
_holder
is the address that owns the tokens being burned._projectId
is the ID of the project to which the burned tokens belong._amount
is the amount of tokens to burn._preferClaimedTokens
is a flag indicating whether there's a preference for tokens to burned from the_holder
s wallet if the project currently has a token contract attached.
- Through the
onlyController
modifier, the function can only be accessed by the controller of the_projectId
. - The function overrides a function definition from the
IJBTokenStore
interface. - The function doesn't return anything.
Body
-
Get a reference to the project's current token.
// Get a reference to the project's current token.
IJBToken _token = tokenOf[_projectId];Internal references:
-
Get a reference to the amount of unclaimed project tokens the holder has.
// Get a reference to the amount of unclaimed project tokens the holder has.
uint256 _unclaimedBalance = unclaimedBalanceOf[_holder][_projectId];Internal references:
-
Get a reference to the amount of the project's tokens the holder has in their wallet. If the project does not yet have tokens issued, the holder must not have a claimed balance.
// Get a reference to the amount of the project's current token the holder has in their wallet.
uint256 _claimedBalance = _token == IJBToken(address(0))
? 0
: _token.balanceOf(_holder, _projectId);External references:
-
Make sure the holder has enough tokens to burn.
// There must be adequate tokens to burn across the holder's claimed and unclaimed balance.
if (_amount > _claimedBalance + _unclaimedBalance) revert INSUFFICIENT_FUNDS(); -
Find the amount of claimed tokens that should be burned. This will remain 0 if the holder has no claimed balance, an amount up to the holder's claimed balance if there is a preference for burning claimed tokens, or the difference between the amount being burned and the holder's unclaimed balance otherwise.
// The amount of tokens to burn.
uint256 _claimedTokensToBurn;
// Get a reference to how many claimed tokens should be burned.
if (_claimedBalance != 0)
if (_preferClaimedTokens)
// If prefer converted, redeem tokens before redeeming unclaimed tokens.
_claimedTokensToBurn = _claimedBalance < _amount ? _claimedBalance : _amount;
// Otherwise, redeem unclaimed tokens before claimed tokens.
else {
unchecked {
_claimedTokensToBurn = _unclaimedBalance < _amount ? _amount - _unclaimedBalance : 0;
}
} -
The amount of unclaimed tokens to burn is necessarily the amount of tokens to burn minus the amount of claimed tokens to burn.
// The amount of unclaimed tokens to redeem.
uint256 _unclaimedTokensToBurn;
unchecked {
_unclaimedTokensToBurn = _amount - _claimedTokensToBurn;
} -
If there are claimed tokens to burn, get a reference to the quantity.
// Subtract the tokens from the unclaimed balance and total supply.
if (_unclaimedTokensToBurn > 0) {
// Reduce the holders balance and the total supply.
unclaimedBalanceOf[_holder][_projectId] =
unclaimedBalanceOf[_holder][_projectId] -
_unclaimedTokensToBurn;
unclaimedTotalSupplyOf[_projectId] =
unclaimedTotalSupplyOf[_projectId] -
_unclaimedTokensToBurn;
}Internal references:
-
If there are claimed tokens to burn, burn them from the holder's wallet.
// Burn the claimed tokens.
if (_claimedTokensToBurn > 0) _token.burn(_projectId, _holder, _claimedTokensToBurn);External references:
-
Emit a
Burn
event with the relevant parameters.emit Burn(
_holder,
_projectId,
_amount,
_unclaimedBalance,
_claimedBalance,
_preferClaimedTokens,
msg.sender
);Event references:
/**
@notice
Burns a project's tokens.
@dev
Only a project's current controller can burn its tokens.
@param _holder The address that owns the tokens being burned.
@param _projectId The ID of the project to which the burned tokens belong.
@param _amount The amount of tokens to burn.
@param _preferClaimedTokens A flag indicating whether there's a preference for tokens to burned from the `_holder`s wallet if the project currently has a token contract attached.
*/
function burnFrom(
address _holder,
uint256 _projectId,
uint256 _amount,
bool _preferClaimedTokens
) external override onlyController(_projectId) {
// Get a reference to the project's current token.
IJBToken _token = tokenOf[_projectId];
// Get a reference to the amount of unclaimed project tokens the holder has.
uint256 _unclaimedBalance = unclaimedBalanceOf[_holder][_projectId];
// Get a reference to the amount of the project's current token the holder has in their wallet.
uint256 _claimedBalance = _token == IJBToken(address(0))
? 0
: _token.balanceOf(_holder, _projectId);
// There must be adequate tokens to burn across the holder's claimed and unclaimed balance.
if (_amount > _claimedBalance + _unclaimedBalance) revert INSUFFICIENT_FUNDS();
// The amount of tokens to burn.
uint256 _claimedTokensToBurn;
// Get a reference to how many claimed tokens should be burned.
if (_claimedBalance != 0)
if (_preferClaimedTokens)
// If prefer converted, redeem tokens before redeeming unclaimed tokens.
_claimedTokensToBurn = _claimedBalance < _amount ? _claimedBalance : _amount;
// Otherwise, redeem unclaimed tokens before claimed tokens.
else {
unchecked {
_claimedTokensToBurn = _unclaimedBalance < _amount ? _amount - _unclaimedBalance : 0;
}
}
// The amount of unclaimed tokens to redeem.
uint256 _unclaimedTokensToBurn;
unchecked {
_unclaimedTokensToBurn = _amount - _claimedTokensToBurn;
}
// Subtract the tokens from the unclaimed balance and total supply.
if (_unclaimedTokensToBurn > 0) {
// Reduce the holders balance and the total supply.
unclaimedBalanceOf[_holder][_projectId] =
unclaimedBalanceOf[_holder][_projectId] -
_unclaimedTokensToBurn;
unclaimedTotalSupplyOf[_projectId] =
unclaimedTotalSupplyOf[_projectId] -
_unclaimedTokensToBurn;
}
// Burn the claimed tokens.
if (_claimedTokensToBurn > 0) _token.burn(_projectId, _holder, _claimedTokensToBurn);
emit Burn(
_holder,
_projectId,
_amount,
_unclaimedBalance,
_claimedBalance,
_preferClaimedTokens,
msg.sender
);
}
String | Description |
---|---|
INSUFFICIENT_FUNDS | Thrown if the holder doesn't have enough tokens to burn. |
Name | Data |
---|---|
Burn |
|
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 |