Skip to content

Commit

Permalink
fix API breaking changes (new Ratio)
Browse files Browse the repository at this point in the history
  • Loading branch information
kk-hainq committed Jan 17, 2022
1 parent bc9dd49 commit cda3928
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 24 deletions.
30 changes: 15 additions & 15 deletions plutus-use-cases/src/Plutus/Contracts/Stablecoin.hs
Expand Up @@ -101,11 +101,11 @@ import Plutus.Contract.StateMachine (AsSMContractError, OnChainState (..), SMCon
import Plutus.Contract.StateMachine qualified as SM
import PlutusTx qualified
import PlutusTx.Prelude
import PlutusTx.Ratio as R
import PlutusTx.Ratio qualified as R
import Prelude qualified as Haskell

-- | Conversion rate from peg currency (eg. USD) to base currency (eg. Ada)
type ConversionRate = Ratio Integer
type ConversionRate = Rational

-- Amounts of stablecoins and reservecoins (used for bookkeeping)
-- SC, RC and BC are values that can be represented on-chain with the 'Value'
Expand Down Expand Up @@ -164,7 +164,7 @@ initialState StateMachineClient{scInstance=SM.StateMachineInstance{SM.typedValid
{-# INLINEABLE convert #-}
-- | Convert peg currency units to base currency units using the
-- observed conversion rate
convert :: ConversionRate -> PC (Ratio Integer) -> BC (Ratio Integer)
convert :: ConversionRate -> PC Rational -> BC Rational
convert rate (PC pc) =
BC $ rate * pc

Expand All @@ -173,7 +173,7 @@ convert rate (PC pc) =
liabilities ::
BankState
-> ConversionRate
-> BC (Ratio Integer)
-> BC Rational
liabilities BankState{bsReserves=BC reserves,bsStablecoins=SC stablecoins} cr =
let BC stableCoinLiabilities = convert cr (PC $ fromInteger stablecoins)
in BC (min (fromInteger reserves) stableCoinLiabilities)
Expand All @@ -184,7 +184,7 @@ liabilities BankState{bsReserves=BC reserves,bsStablecoins=SC stablecoins} cr =
equity ::
BankState
-> ConversionRate
-> BC (Ratio Integer)
-> BC Rational
equity r@BankState{bsReserves=BC reserves} cr =
let BC l = liabilities r cr
in BC (fromInteger reserves - l)
Expand All @@ -193,9 +193,9 @@ equity r@BankState{bsReserves=BC reserves} cr =
data Stablecoin =
Stablecoin
{ scOracle :: PaymentPubKey -- ^ Public key of the oracle that provides exchange rates
, scFee :: Ratio Integer -- ^ Fee charged by bank for transactions. Calculated as a fraction of the total transaction volume in base currency.
, scMinReserveRatio :: Ratio Integer -- ^ The minimum ratio of reserves to liabilities
, scMaxReserveRatio :: Ratio Integer -- ^ The maximum ratio of reserves to liabilities
, scFee :: Rational -- ^ Fee charged by bank for transactions. Calculated as a fraction of the total transaction volume in base currency.
, scMinReserveRatio :: Rational -- ^ The minimum ratio of reserves to liabilities
, scMaxReserveRatio :: Rational -- ^ The maximum ratio of reserves to liabilities
, scReservecoinDefaultPrice :: BC Integer -- ^ The price of a single reservecoin if no reservecoins have been issued
, scBaseCurrency :: AssetClass -- ^ The asset class of the base currency. Value of this currency will be locked by the stablecoin state machine instance
, scStablecoinTokenName :: TokenName -- ^ 'TokenName' of the stablecoin
Expand All @@ -207,7 +207,7 @@ data Stablecoin =
{-# INLINEABLE minReserve #-}
-- | Minimum number of base currency coins held by the bank.
-- Returns 'Nothing' if no stablecoins have been minted.
minReserve :: Stablecoin -> ConversionRate -> BankState -> Maybe (BC (Ratio Integer))
minReserve :: Stablecoin -> ConversionRate -> BankState -> Maybe (BC Rational)
minReserve Stablecoin{scMinReserveRatio} cr BankState{bsStablecoins=SC sc}
| sc == zero = Nothing
| otherwise =
Expand All @@ -217,7 +217,7 @@ minReserve Stablecoin{scMinReserveRatio} cr BankState{bsStablecoins=SC sc}
-- | Maximum number of base currency coins held by the bank.
-- Returns 'Nothing' if no stablecoins have been minted.
{-# INLINEABLE maxReserve #-}
maxReserve :: Stablecoin -> ConversionRate -> BankState -> Maybe (BC (Ratio Integer))
maxReserve :: Stablecoin -> ConversionRate -> BankState -> Maybe (BC Rational)
maxReserve Stablecoin{scMaxReserveRatio} cr BankState{bsStablecoins=SC sc}
| sc == zero = Nothing
| otherwise =
Expand All @@ -226,15 +226,15 @@ maxReserve Stablecoin{scMaxReserveRatio} cr BankState{bsStablecoins=SC sc}

{-# INLINEABLE reservecoinNominalPrice #-}
-- | Price of a single reservecoin in base currency
reservecoinNominalPrice :: Stablecoin -> BankState -> ConversionRate -> BC (Ratio Integer)
reservecoinNominalPrice :: Stablecoin -> BankState -> ConversionRate -> BC Rational
reservecoinNominalPrice Stablecoin{scReservecoinDefaultPrice} bankState@BankState{bsReservecoins=RC rc} cr
| rc /= 0 = let BC e = equity bankState cr in BC (e * R.recip (fromInteger rc))
| otherwise = fmap fromInteger scReservecoinDefaultPrice

{-# INLINEABLE stablecoinNominalPrice #-}
-- | Price of a single stablecoin in base currency. If the banks' liabilities
-- exceed its reserves then 'stablecoinNominalPrice' is zero.
stablecoinNominalPrice :: BankState -> ConversionRate -> BC (Ratio Integer)
stablecoinNominalPrice :: BankState -> ConversionRate -> BC Rational
stablecoinNominalPrice bankState@BankState{bsStablecoins=SC sc} cr
| sc == zero = BC p
| otherwise = BC $ min p l
Expand All @@ -252,7 +252,7 @@ data SCAction
{-# INLINEABLE calcFees #-}
-- | Calculate transaction fees (paid in base currency to the bank) as a
-- fraction of the transaction's volume
calcFees :: Stablecoin -> BankState -> ConversionRate -> SCAction -> BC (Ratio Integer)
calcFees :: Stablecoin -> BankState -> ConversionRate -> SCAction -> BC Rational
calcFees sc@Stablecoin{scFee} bs conversionRate = \case
MintStablecoin (SC i) ->
stablecoinNominalPrice bs conversionRate * BC scFee * (BC $ abs $ fromInteger i)
Expand Down Expand Up @@ -352,8 +352,8 @@ data InvalidStateReason
= NegativeReserveCoins
| NegativeReserves
| NegativeStablecoins
| MinReserves { allowed :: BC (Ratio Integer), actual :: BC (Ratio Integer) }
| MaxReserves { allowed :: BC (Ratio Integer), actual :: BC (Ratio Integer) }
| MinReserves { allowed :: BC Rational, actual :: BC Rational }
| MaxReserves { allowed :: BC Rational, actual :: BC Rational }
| NegativeLiabilities
| NegativeEquity
deriving (Haskell.Show)
Expand Down
4 changes: 2 additions & 2 deletions plutus-use-cases/src/Plutus/Contracts/Uniswap/Pool.hs
Expand Up @@ -12,7 +12,7 @@ module Plutus.Contracts.Uniswap.Pool

import Ledger.Value (TokenName (..), unAssetClass, unCurrencySymbol)
import Plutus.Contracts.Uniswap.Types
import PlutusTx.Prelude
import PlutusTx.Prelude hiding (ratio)
import PlutusTx.Sqrt

{-# INLINABLE calculateInitialLiquidity #-}
Expand All @@ -34,7 +34,7 @@ calculateAdditionalLiquidity oldA' oldB' liquidity delA' delB' =
Exactly x -> Amount x - liquidity
Approximately x -> Amount x - liquidity
where
ratio = (unAmount (liquidity * liquidity * newProd)) % unAmount oldProd
ratio = unsafeRatio (unAmount (liquidity * liquidity * newProd)) (unAmount oldProd)

-- Unwrap, as we're combining terms
oldA = unAmount oldA'
Expand Down
14 changes: 7 additions & 7 deletions plutus-use-cases/test/Spec/Stablecoin.hs
Expand Up @@ -15,7 +15,7 @@ module Spec.Stablecoin(
import Control.Lens (preview)
import Control.Monad (void)
import Data.Maybe (listToMaybe, mapMaybe)
import Prelude hiding (negate)
import Prelude hiding (Rational, negate)

import Ledger.Ada (adaSymbol, adaToken)
import Ledger.Ada qualified as Ada
Expand All @@ -36,7 +36,7 @@ import Plutus.Trace.Emulator (ContractHandle, EmulatorTrace)
import Plutus.Trace.Emulator qualified as Trace
import Plutus.Trace.Emulator.Types (_ContractLog, cilMessage)
import PlutusTx.Numeric (negate, one, zero)
import PlutusTx.Ratio as Ratio
import PlutusTx.Ratio qualified as R
import Wallet.Emulator.MultiAgent (eteEvent)

import Test.Tasty
Expand All @@ -47,15 +47,15 @@ user = w1
oraclePrivateKey :: PaymentPrivateKey
oraclePrivateKey = CW.paymentPrivateKey $ CW.fromWalletNumber $ CW.WalletNumber 2

onePercent :: Ratio Integer
onePercent = 1 % 100
onePercent :: R.Rational
onePercent = R.unsafeRatio 1 100

coin :: Stablecoin
coin = Stablecoin
{ scOracle = PaymentPubKey $ toPublicKey (unPaymentPrivateKey oraclePrivateKey)
, scFee = onePercent
, scMinReserveRatio = zero
, scMaxReserveRatio = 4 % 1
, scMaxReserveRatio = R.unsafeRatio 4 1
, scReservecoinDefaultPrice = BC 1
, scBaseCurrency = Value.assetClass adaSymbol adaToken
, scStablecoinTokenName = "stablecoin"
Expand Down Expand Up @@ -101,7 +101,7 @@ tests = testGroup "Stablecoin"
)
stablecoinTrace

, let expectedLogMsg = "New state is invalid: MaxReserves {allowed = BC {unBC = (20000000 % 1)}, actual = BC {unBC = (20173235 % 1)}}. The transition is not allowed." in
, let expectedLogMsg = "New state is invalid: MaxReserves {allowed = BC {unBC = Rational 20000000 1}, actual = BC {unBC = Rational 20173235 1}}. The transition is not allowed." in
checkPredicate "Cannot exceed the maximum reserve ratio"
(valueAtAddress stablecoinAddress (== (initialDeposit <> initialFee <> Ada.lovelaceValueOf 5_050_000))
.&&. assertNoFailedTransactions
Expand Down Expand Up @@ -156,7 +156,7 @@ stablecoinTrace = do
mintReserveCoins (RC 10_000_000) one hdl
mintStableCoins (SC 5_000_000) one hdl
-- redeem 2M stablecoins at an exchange rate of 2 Ada : 1 USD (so we get 4 Ada from the bank)
redeemStableCoins (SC 2_000_000) (Ratio.fromInteger 2) hdl
redeemStableCoins (SC 2_000_000) (R.fromInteger 2) hdl

-- | Mint 100 reserve coins, mint 50 stablecoins, then attempt to mint
-- another 49 reserve coins. This fails because the max. reserve ratio
Expand Down

0 comments on commit cda3928

Please sign in to comment.