@@ -150,6 +150,8 @@ data PreprocessedTokenOperation
150150 { ptgoTarget :: ! CborTokenHolder }
151151 | PTOTokenRemoveDenyList
152152 { ptgoTarget :: ! CborTokenHolder }
153+ | PTOTokenPause
154+ | PTOTokenUnpause
153155 deriving (Eq , Show )
154156
155157-- | Convert 'TokenAmount's to 'TokenRawAmount's, checking that they are within
@@ -195,6 +197,8 @@ preprocessTokenUpdateTransaction decimals = mapM preproc . tokenOperations
195197 return PTOTokenAddDenyList {ptgoTarget = receiver}
196198 preproc (TokenRemoveDenyList receiver) =
197199 return PTOTokenRemoveDenyList {ptgoTarget = receiver}
200+ preproc TokenPause = return PTOTokenPause
201+ preproc TokenUnpause = return PTOTokenUnpause
198202
199203-- | Encode and log a 'TokenEvent'.
200204logEncodeTokenEvent :: (PLTKernelUpdate m ) => TokenEvent -> m ()
@@ -228,6 +232,7 @@ executeTokenUpdateTransaction TransactionContext{..} tokenParam = do
228232 let handleOperation ! opIndex op = do
229233 case op of
230234 PTOTransfer {.. } -> do
235+ checkPaused opIndex " transfer"
231236 recipientAccount <- requireAccount opIndex pthoRecipient
232237 -- If the allow list is enabled, check that the sender and recipient are
233238 -- both on the allow list.
@@ -304,6 +309,7 @@ executeTokenUpdateTransaction TransactionContext{..} tokenParam = do
304309 }
305310 case tokenGovernanceOp of
306311 PTOTokenMint {.. } -> do
312+ checkPaused opIndex " mint"
307313 requireFeature opIndex " mint" " mintable"
308314 pltTickEnergy tokenMintCost
309315 mintOK <- mint tcSender ptgoAmount
@@ -318,6 +324,7 @@ executeTokenUpdateTransaction TransactionContext{..} tokenParam = do
318324 toTokenAmount decimals (maxBound :: TokenRawAmount )
319325 }
320326 PTOTokenBurn {.. } -> do
327+ checkPaused opIndex " burn"
321328 requireFeature opIndex " burn" " burnable"
322329 pltTickEnergy tokenBurnCost
323330 burnOK <- burn tcSender ptgoAmount
@@ -353,12 +360,29 @@ executeTokenUpdateTransaction TransactionContext{..} tokenParam = do
353360 pltTickEnergy tokenListOperationCost
354361 setAccountState account " denyList" Nothing
355362 logEncodeTokenEvent (RemoveDenyListEvent ptgoTarget)
363+ PTOTokenPause -> do
364+ pltTickEnergy tokenPauseUnpauseCost
365+ setModuleState " paused" (Just " " )
366+ logEncodeTokenEvent Pause
367+ PTOTokenUnpause -> do
368+ pltTickEnergy tokenPauseUnpauseCost
369+ setModuleState " paused" Nothing
370+ logEncodeTokenEvent Unpause
356371 return (opIndex + 1 )
357372 foldM_ handleOperation 0 operations
358373 where
359374 tokenParamLBS =
360375 BS.Builder. toLazyByteString $ BS.Builder. shortByteString $ parameterBytes tokenParam
361376 failTH = pltError . encodeTokenRejectReason
377+ checkPaused opIndex op = do
378+ paused <- isJust <$> getModuleState " paused"
379+ when paused $
380+ failTH
381+ OperationNotPermitted
382+ { trrOperationIndex = opIndex,
383+ trrAddressNotPermitted = Nothing ,
384+ trrReason = Just $ Text. pack $ " token operation " ++ op ++ " is paused"
385+ }
362386
363387-- | Token state key prefix for global module state.
364388moduleStatePrefix :: Word16
@@ -472,6 +496,7 @@ queryTokenModuleState = do
472496 Nothing -> pltError $ QTEInvariantViolation " Governance account does not exist"
473497 Just account -> return account
474498 accountTokenHolderShort <$> getAccountCanonicalAddress account
499+ tmsPaused <- Just . isJust <$> getModuleState " paused"
475500 tmsAllowList <- Just . isJust <$> getModuleState " allowList"
476501 tmsDenyList <- Just . isJust <$> getModuleState " denyList"
477502 tmsMintable <- Just . isJust <$> getModuleState " mintable"
0 commit comments