@@ -23,6 +23,7 @@ abstract contract ERC20Mintable is ERC20Base, IERC20Mintable {
2323        uint16  maxPendingPremintsCount;
2424        mapping (uint256  =>  uint256 ) premintReschedulings;
2525        mapping (uint256  =>  uint256 ) premintReschedulingCounters;
26+         uint256  totalReserveSupply;
2627    }
2728
2829    /// @notice The structure that represents an array of premint records 
@@ -106,6 +107,9 @@ abstract contract ERC20Mintable is ERC20Base, IERC20Mintable {
106107    /// @notice The provided value cannot be cast to uint64 type 
107108    error InappropriateUint64Value  (uint256  value );
108109
110+     /// @notice The amount of tokens to burn is greater than the total reserve supply 
111+     error InsufficientReserveSupply  ();
112+ 
109113    // -------------------- Modifiers -------------------------------- 
110114
111115    /** 
@@ -231,6 +235,25 @@ abstract contract ERC20Mintable is ERC20Base, IERC20Mintable {
231235        return  _mintInternal (account, amount);
232236    }
233237
238+     /** 
239+      * @inheritdoc IERC20Mintable 
240+      * 
241+      * @dev The contract must not be paused 
242+      * @dev Can only be called by a minter account 
243+      * @dev The message sender must not be blocklisted 
244+      */ 
245+     function mintFromReserve  (
246+         address  account ,
247+         uint256  amount 
248+     ) external  whenNotPaused onlyMinter notBlocklisted (_msgSender ()) {
249+         _mintInternal (account, amount);
250+ 
251+         ExtendedStorageSlot storage  storageSlot =  _getExtendedStorageSlot ();
252+         storageSlot.totalReserveSupply +=  amount;
253+ 
254+         emit  MintFromReserve (_msgSender (), account, amount, storageSlot.totalReserveSupply);
255+     }
256+ 
234257    /** 
235258     * @inheritdoc IERC20Mintable 
236259     * 
@@ -308,6 +331,30 @@ abstract contract ERC20Mintable is ERC20Base, IERC20Mintable {
308331        _burnInternal (_msgSender (), amount);
309332    }
310333
334+     /** 
335+      * @inheritdoc IERC20Mintable 
336+      * 
337+      * @dev The contract must not be paused 
338+      * @dev Can only be called by a minter account 
339+      * @dev The message sender must not be blocklisted 
340+      * @dev The amount of tokens to burn must be less than or equal to the total reserve supply 
341+      */ 
342+     function burnToReserve  (uint256  amount ) external  whenNotPaused onlyMinter notBlocklisted (_msgSender ()) {
343+         _burnInternal (_msgSender (), amount);
344+ 
345+         ExtendedStorageSlot storage  storageSlot =  _getExtendedStorageSlot ();
346+ 
347+         if  (storageSlot.totalReserveSupply <  amount) {
348+             revert  InsufficientReserveSupply ();
349+         }
350+ 
351+         unchecked  {
352+             storageSlot.totalReserveSupply -=  amount;
353+         }
354+ 
355+         emit  BurnToReserve (_msgSender (), amount, storageSlot.totalReserveSupply);
356+     }
357+ 
311358    /** 
312359     * @notice Returns the total amount of preminted tokens 
313360     * @param account The account to check the preminted balance for 
@@ -385,6 +432,14 @@ abstract contract ERC20Mintable is ERC20Base, IERC20Mintable {
385432        return  _mintersAllowance[minter];
386433    }
387434
435+     /** 
436+      * @inheritdoc IERC20Mintable 
437+      */ 
438+     function totalReserveSupply  () external  view  returns  (uint256 ) {
439+         ExtendedStorageSlot storage  storageSlot =  _getExtendedStorageSlot ();
440+         return  storageSlot.totalReserveSupply;
441+     }
442+ 
388443    function _mintInternal  (address  account , uint256  amount ) internal  returns  (bool ) {
389444        if  (amount ==  0 ) {
390445            revert  ZeroMintAmount ();
0 commit comments