{-# LANGUAGE ViewPatterns #-}
module Plutus.Contract.Test.MissingLovelace
( calculateDelta
) where
import Ledger.Value.CardanoAPI qualified as Value
calculateDelta
:: Value.Value
-> Value.Lovelace
-> Value.Lovelace
-> [Value.Lovelace]
-> Value.Value
calculateDelta :: Value -> Lovelace -> Lovelace -> [Lovelace] -> Value
calculateDelta Value
expectedDelta Lovelace
initialValue Lovelace
finalValue [Lovelace]
allWalletsTxOutCosts =
let
expectedAda :: Lovelace
expectedAda = Value -> Lovelace
Value.selectLovelace Value
expectedDelta
deltas :: [Lovelace]
deltas = (Lovelace -> Lovelace) -> [Lovelace] -> [Lovelace]
forall a b. (a -> b) -> [a] -> [b]
map Lovelace -> Lovelace
forall a. Num a => a -> a
abs ([Lovelace] -> [Lovelace]) -> [Lovelace] -> [Lovelace]
forall a b. (a -> b) -> a -> b
$ [[Lovelace]] -> [Lovelace]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ Lovelace -> Lovelace
forall a. Num a => a -> a
abs Lovelace
val Lovelace -> Lovelace -> Lovelace
forall a. Num a => a -> a -> a
- Lovelace -> Lovelace
forall a. Num a => a -> a
abs Lovelace
wCost
, Lovelace -> Lovelace
forall a. Num a => a -> a
abs Lovelace
val Lovelace -> Lovelace -> Lovelace
forall a. Num a => a -> a -> a
+ Lovelace -> Lovelace
forall a. Num a => a -> a
abs Lovelace
wCost ] | Lovelace
val <- [Lovelace
expectedAda, Lovelace
0] [Lovelace] -> [Lovelace] -> [Lovelace]
forall a. [a] -> [a] -> [a]
++ [Lovelace]
allWalletsTxOutCosts
, Lovelace
wCost <- [Lovelace]
allWalletsTxOutCosts ]
realDelta :: Lovelace
realDelta = Lovelace
finalValue Lovelace -> Lovelace -> Lovelace
forall a. Num a => a -> a -> a
- Lovelace
initialValue
missingDelta :: Value
missingDelta =
if [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or [Lovelace -> Lovelace
forall a. Num a => a -> a
abs Lovelace
realDelta Lovelace -> Lovelace -> Lovelace
forall a. Integral a => a -> a -> a
`mod` Lovelace
d Lovelace -> Lovelace -> Bool
forall a. Eq a => a -> a -> Bool
== Lovelace
0 | Lovelace
d <- [Lovelace]
deltas, Lovelace
d Lovelace -> Lovelace -> Bool
forall a. Eq a => a -> a -> Bool
/= Lovelace
0] then
let missingAda :: Value
missingAda = Lovelace -> Value
Value.lovelaceToValue Lovelace
realDelta
missingNonAda :: Value
missingNonAda = Value -> Value
Value.noAdaValue Value
expectedDelta
in Value
missingAda Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
missingNonAda
else Value
expectedDelta
in
if Lovelace
expectedAda Lovelace -> Lovelace -> Bool
forall a. Eq a => a -> a -> Bool
== Lovelace
realDelta then Value
expectedDelta
else Value
missingDelta