module Cooked.Attack.AddToken
( addTokenAttack,
AddTokenLbl (..),
dupTokenAttack,
DupTokenLbl (..),
)
where
import Control.Monad
import Cooked.Pretty
import Cooked.Skeleton
import Cooked.Tweak
import Data.Map qualified as Map
import Optics.Core
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V3 qualified as Api
import PlutusTx.Numeric qualified as PlutusTx
import Prettyprinter qualified as PP
addTokenAttack ::
(MonadTweak m, IsTxSkelOutAllowedOwner o) =>
(VScript -> [(Api.TokenName, Integer)]) ->
o ->
m Api.Value
addTokenAttack :: forall (m :: * -> *) o.
(MonadTweak m, IsTxSkelOutAllowedOwner o) =>
(VScript -> [(TokenName, Integer)]) -> o -> m Value
addTokenAttack VScript -> [(TokenName, Integer)]
extraTokens o
attacker = do
[VScript]
currencies <- Optic' A_Getter '[] TxSkel [VScript] -> m [VScript]
forall (m :: * -> *) k (is :: IxList) a.
(MonadTweak m, Is k A_Getter) =>
Optic' k is TxSkel a -> m a
viewTweak (Lens' TxSkel TxSkelMints
txSkelMintsL Lens' TxSkel TxSkelMints
-> Optic
A_Getter
'[]
TxSkelMints
TxSkelMints
[(VScript, TokenName)]
[(VScript, TokenName)]
-> Optic
A_Getter
'[]
TxSkel
TxSkel
[(VScript, TokenName)]
[(VScript, TokenName)]
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
A_Getter
'[]
TxSkelMints
TxSkelMints
[(VScript, TokenName)]
[(VScript, TokenName)]
txSkelMintsAssetClassesG Optic
A_Getter
'[]
TxSkel
TxSkel
[(VScript, TokenName)]
[(VScript, TokenName)]
-> Optic
A_Getter
'[]
[(VScript, TokenName)]
[(VScript, TokenName)]
[VScript]
[VScript]
-> Optic' A_Getter '[] TxSkel [VScript]
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% ([(VScript, TokenName)] -> [VScript])
-> Optic
A_Getter
'[]
[(VScript, TokenName)]
[(VScript, TokenName)]
[VScript]
[VScript]
forall s a. (s -> a) -> Getter s a
to (((VScript, TokenName) -> VScript)
-> [(VScript, TokenName)] -> [VScript]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (VScript, TokenName) -> VScript
forall a b. (a, b) -> a
fst))
Value
oldMintsValue <- Optic' A_Getter '[] TxSkel Value -> m Value
forall (m :: * -> *) k (is :: IxList) a.
(MonadTweak m, Is k A_Getter) =>
Optic' k is TxSkel a -> m a
viewTweak (Lens' TxSkel TxSkelMints
txSkelMintsL Lens' TxSkel TxSkelMints
-> Optic A_Getter '[] TxSkelMints TxSkelMints Value Value
-> Optic' A_Getter '[] TxSkel Value
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% (TxSkelMints -> Value)
-> Optic A_Getter '[] TxSkelMints TxSkelMints Value Value
forall s a. (s -> a) -> Getter s a
to TxSkelMints -> Value
forall a. ToValue a => a -> Value
Script.toValue)
[(VScript, TokenName, Integer)]
-> ((VScript, TokenName, Integer) -> m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(VScript
mp, TokenName
tk, Integer
n) | VScript
mp <- [VScript]
currencies, (TokenName
tk, Integer
n) <- VScript -> [(TokenName, Integer)]
extraTokens VScript
mp] (((VScript, TokenName, Integer) -> m ()) -> m ())
-> ((VScript, TokenName, Integer) -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \(VScript
mp, TokenName
tk, Integer
n) ->
Optic' A_Lens '[] TxSkel Integer -> (Integer -> Integer) -> m ()
forall (m :: * -> *) k (is :: IxList) a.
(MonadTweak m, Is k A_Setter) =>
Optic' k is TxSkel a -> (a -> a) -> m ()
overTweak (Lens' TxSkel TxSkelMints
txSkelMintsL Lens' TxSkel TxSkelMints
-> Optic
A_Lens
'[]
TxSkelMints
TxSkelMints
(Maybe TxSkelRedeemer, Integer)
(Maybe TxSkelRedeemer, Integer)
-> Optic
A_Lens
'[]
TxSkel
TxSkel
(Maybe TxSkelRedeemer, Integer)
(Maybe TxSkelRedeemer, Integer)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% VScript
-> TokenName
-> Optic
A_Lens
'[]
TxSkelMints
TxSkelMints
(Maybe TxSkelRedeemer, Integer)
(Maybe TxSkelRedeemer, Integer)
forall mp.
(ToVScript mp, Typeable mp) =>
mp
-> TokenName
-> Optic
A_Lens
'[]
TxSkelMints
TxSkelMints
(Maybe TxSkelRedeemer, Integer)
(Maybe TxSkelRedeemer, Integer)
txSkelMintsAssetClassAmountL VScript
mp TokenName
tk Optic
A_Lens
'[]
TxSkel
TxSkel
(Maybe TxSkelRedeemer, Integer)
(Maybe TxSkelRedeemer, Integer)
-> Optic
A_Lens
'[]
(Maybe TxSkelRedeemer, Integer)
(Maybe TxSkelRedeemer, Integer)
Integer
Integer
-> Optic' A_Lens '[] TxSkel Integer
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
A_Lens
'[]
(Maybe TxSkelRedeemer, Integer)
(Maybe TxSkelRedeemer, Integer)
Integer
Integer
forall s t a b. Field2 s t a b => Lens s t a b
_2) (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
n)
Value
totalIncrement <- Optic' A_Getter '[] TxSkel Value -> m Value
forall (m :: * -> *) k (is :: IxList) a.
(MonadTweak m, Is k A_Getter) =>
Optic' k is TxSkel a -> m a
viewTweak (Lens' TxSkel TxSkelMints
txSkelMintsL Lens' TxSkel TxSkelMints
-> Optic A_Getter '[] TxSkelMints TxSkelMints Value Value
-> Optic' A_Getter '[] TxSkel Value
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% (TxSkelMints -> Value)
-> Optic A_Getter '[] TxSkelMints TxSkelMints Value Value
forall s a. (s -> a) -> Getter s a
to TxSkelMints -> Value
forall a. ToValue a => a -> Value
Script.toValue Optic' A_Getter '[] TxSkel Value
-> Optic A_Getter '[] Value Value Value Value
-> Optic' A_Getter '[] TxSkel Value
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% (Value -> Value) -> Optic A_Getter '[] Value Value Value Value
forall s a. (s -> a) -> Getter s a
to (Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value -> Value
forall a. AdditiveGroup a => a -> a
PlutusTx.negate Value
oldMintsValue))
Bool -> m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Value
totalIncrement Value -> Value -> Bool
forall a. Eq a => a -> a -> Bool
/= Value
forall a. Monoid a => a
mempty)
TxSkelOut -> m ()
forall (m :: * -> *). MonadTweak m => TxSkelOut -> m ()
addOutputTweak (TxSkelOut -> m ()) -> TxSkelOut -> m ()
forall a b. (a -> b) -> a -> b
$ o
attacker o -> Payable '[ 'IsValue] -> TxSkelOut
forall owner (els :: [PayableKind]).
IsTxSkelOutAllowedOwner owner =>
owner -> Payable els -> TxSkelOut
`receives` Value -> Payable '[ 'IsValue]
forall a1. ToValue a1 => a1 -> Payable '[ 'IsValue]
Value Value
totalIncrement
AddTokenLbl -> m ()
forall (m :: * -> *) x. (MonadTweak m, LabelConstrs x) => x -> m ()
addLabelTweak AddTokenLbl
AddTokenLbl
Value -> m Value
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Value
totalIncrement
dupTokenAttack ::
(MonadTweak m, IsTxSkelOutAllowedOwner o) =>
(VScript -> Api.TokenName -> Integer -> Integer) ->
o ->
m Api.Value
dupTokenAttack :: forall (m :: * -> *) o.
(MonadTweak m, IsTxSkelOutAllowedOwner o) =>
(VScript -> TokenName -> Integer -> Integer) -> o -> m Value
dupTokenAttack VScript -> TokenName -> Integer -> Integer
change o
attacker = do
TxSkelMints
mints <- Lens' TxSkel TxSkelMints -> m TxSkelMints
forall (m :: * -> *) k (is :: IxList) a.
(MonadTweak m, Is k A_Getter) =>
Optic' k is TxSkel a -> m a
viewTweak Lens' TxSkel TxSkelMints
txSkelMintsL
Value
res <-
(VScript -> [(TokenName, Integer)]) -> o -> m Value
forall (m :: * -> *) o.
(MonadTweak m, IsTxSkelOutAllowedOwner o) =>
(VScript -> [(TokenName, Integer)]) -> o -> m Value
addTokenAttack
( \VScript
s ->
[(TokenName, Integer)]
-> ((TxSkelRedeemer, Map TokenName Integer)
-> [(TokenName, Integer)])
-> Maybe (TxSkelRedeemer, Map TokenName Integer)
-> [(TokenName, Integer)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
[]
(\(TxSkelRedeemer
_, Map TokenName Integer
subMap) -> [(TokenName
tk, VScript -> TokenName -> Integer -> Integer
change VScript
s TokenName
tk Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
n) | (TokenName
tk, Integer
n) <- Map TokenName Integer -> [(TokenName, Integer)]
forall k a. Map k a -> [(k, a)]
Map.toList Map TokenName Integer
subMap])
(Optic'
A_Lens
'[]
TxSkelMints
(Maybe (TxSkelRedeemer, Map TokenName Integer))
-> TxSkelMints -> Maybe (TxSkelRedeemer, Map TokenName Integer)
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view (VScript
-> Optic'
A_Lens
'[]
TxSkelMints
(Maybe (TxSkelRedeemer, Map TokenName Integer))
forall mp.
(ToVScript mp, Typeable mp) =>
mp
-> Optic'
A_Lens
'[]
TxSkelMints
(Maybe (TxSkelRedeemer, Map TokenName Integer))
txSkelMintsPolicyTokensL VScript
s) TxSkelMints
mints)
)
o
attacker
AddTokenLbl -> m ()
forall (m :: * -> *) x. (MonadTweak m, LabelConstrs x) => x -> m ()
removeLabelTweak AddTokenLbl
AddTokenLbl
DupTokenLbl -> m ()
forall (m :: * -> *) x. (MonadTweak m, LabelConstrs x) => x -> m ()
addLabelTweak DupTokenLbl
DupTokenLbl
Value -> m Value
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Value
res
data AddTokenLbl = AddTokenLbl deriving (Int -> AddTokenLbl -> ShowS
[AddTokenLbl] -> ShowS
AddTokenLbl -> String
(Int -> AddTokenLbl -> ShowS)
-> (AddTokenLbl -> String)
-> ([AddTokenLbl] -> ShowS)
-> Show AddTokenLbl
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AddTokenLbl -> ShowS
showsPrec :: Int -> AddTokenLbl -> ShowS
$cshow :: AddTokenLbl -> String
show :: AddTokenLbl -> String
$cshowList :: [AddTokenLbl] -> ShowS
showList :: [AddTokenLbl] -> ShowS
Show, AddTokenLbl -> AddTokenLbl -> Bool
(AddTokenLbl -> AddTokenLbl -> Bool)
-> (AddTokenLbl -> AddTokenLbl -> Bool) -> Eq AddTokenLbl
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AddTokenLbl -> AddTokenLbl -> Bool
== :: AddTokenLbl -> AddTokenLbl -> Bool
$c/= :: AddTokenLbl -> AddTokenLbl -> Bool
/= :: AddTokenLbl -> AddTokenLbl -> Bool
Eq, Eq AddTokenLbl
Eq AddTokenLbl =>
(AddTokenLbl -> AddTokenLbl -> Ordering)
-> (AddTokenLbl -> AddTokenLbl -> Bool)
-> (AddTokenLbl -> AddTokenLbl -> Bool)
-> (AddTokenLbl -> AddTokenLbl -> Bool)
-> (AddTokenLbl -> AddTokenLbl -> Bool)
-> (AddTokenLbl -> AddTokenLbl -> AddTokenLbl)
-> (AddTokenLbl -> AddTokenLbl -> AddTokenLbl)
-> Ord AddTokenLbl
AddTokenLbl -> AddTokenLbl -> Bool
AddTokenLbl -> AddTokenLbl -> Ordering
AddTokenLbl -> AddTokenLbl -> AddTokenLbl
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: AddTokenLbl -> AddTokenLbl -> Ordering
compare :: AddTokenLbl -> AddTokenLbl -> Ordering
$c< :: AddTokenLbl -> AddTokenLbl -> Bool
< :: AddTokenLbl -> AddTokenLbl -> Bool
$c<= :: AddTokenLbl -> AddTokenLbl -> Bool
<= :: AddTokenLbl -> AddTokenLbl -> Bool
$c> :: AddTokenLbl -> AddTokenLbl -> Bool
> :: AddTokenLbl -> AddTokenLbl -> Bool
$c>= :: AddTokenLbl -> AddTokenLbl -> Bool
>= :: AddTokenLbl -> AddTokenLbl -> Bool
$cmax :: AddTokenLbl -> AddTokenLbl -> AddTokenLbl
max :: AddTokenLbl -> AddTokenLbl -> AddTokenLbl
$cmin :: AddTokenLbl -> AddTokenLbl -> AddTokenLbl
min :: AddTokenLbl -> AddTokenLbl -> AddTokenLbl
Ord)
instance PrettyCooked AddTokenLbl where
prettyCooked :: AddTokenLbl -> DocCooked
prettyCooked = AddTokenLbl -> DocCooked
forall a ann. Show a => a -> Doc ann
PP.viaShow
data DupTokenLbl = DupTokenLbl
deriving (DupTokenLbl -> DupTokenLbl -> Bool
(DupTokenLbl -> DupTokenLbl -> Bool)
-> (DupTokenLbl -> DupTokenLbl -> Bool) -> Eq DupTokenLbl
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DupTokenLbl -> DupTokenLbl -> Bool
== :: DupTokenLbl -> DupTokenLbl -> Bool
$c/= :: DupTokenLbl -> DupTokenLbl -> Bool
/= :: DupTokenLbl -> DupTokenLbl -> Bool
Eq, Int -> DupTokenLbl -> ShowS
[DupTokenLbl] -> ShowS
DupTokenLbl -> String
(Int -> DupTokenLbl -> ShowS)
-> (DupTokenLbl -> String)
-> ([DupTokenLbl] -> ShowS)
-> Show DupTokenLbl
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DupTokenLbl -> ShowS
showsPrec :: Int -> DupTokenLbl -> ShowS
$cshow :: DupTokenLbl -> String
show :: DupTokenLbl -> String
$cshowList :: [DupTokenLbl] -> ShowS
showList :: [DupTokenLbl] -> ShowS
Show, Eq DupTokenLbl
Eq DupTokenLbl =>
(DupTokenLbl -> DupTokenLbl -> Ordering)
-> (DupTokenLbl -> DupTokenLbl -> Bool)
-> (DupTokenLbl -> DupTokenLbl -> Bool)
-> (DupTokenLbl -> DupTokenLbl -> Bool)
-> (DupTokenLbl -> DupTokenLbl -> Bool)
-> (DupTokenLbl -> DupTokenLbl -> DupTokenLbl)
-> (DupTokenLbl -> DupTokenLbl -> DupTokenLbl)
-> Ord DupTokenLbl
DupTokenLbl -> DupTokenLbl -> Bool
DupTokenLbl -> DupTokenLbl -> Ordering
DupTokenLbl -> DupTokenLbl -> DupTokenLbl
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: DupTokenLbl -> DupTokenLbl -> Ordering
compare :: DupTokenLbl -> DupTokenLbl -> Ordering
$c< :: DupTokenLbl -> DupTokenLbl -> Bool
< :: DupTokenLbl -> DupTokenLbl -> Bool
$c<= :: DupTokenLbl -> DupTokenLbl -> Bool
<= :: DupTokenLbl -> DupTokenLbl -> Bool
$c> :: DupTokenLbl -> DupTokenLbl -> Bool
> :: DupTokenLbl -> DupTokenLbl -> Bool
$c>= :: DupTokenLbl -> DupTokenLbl -> Bool
>= :: DupTokenLbl -> DupTokenLbl -> Bool
$cmax :: DupTokenLbl -> DupTokenLbl -> DupTokenLbl
max :: DupTokenLbl -> DupTokenLbl -> DupTokenLbl
$cmin :: DupTokenLbl -> DupTokenLbl -> DupTokenLbl
min :: DupTokenLbl -> DupTokenLbl -> DupTokenLbl
Ord)
instance PrettyCooked DupTokenLbl where
prettyCooked :: DupTokenLbl -> DocCooked
prettyCooked DupTokenLbl
_ = DocCooked
"DupToken"