-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[vesting] rewrite the private sale module #75
Changes from 2 commits
2942a57
eb1c725
0ac9298
8f3ec5d
b751353
0d6a3e3
0a60a26
2feceb4
6f80c86
6ac20cf
fe04fc8
3f7b121
fba8968
01df2d6
f44f3c1
504095c
469e882
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#!/bin/bash | ||
|
||
# This script is a wrapper around cardano-address. | ||
# | ||
# By default, cardano-address takes its input from stdin. For now, piping with | ||
# (|>) from Shh.Internal leads to unexpected behaviour when doing IO inside the | ||
# PropertyM transformer of QuickCheck. With (|>)¸the command cardano-address | ||
# sometimes does not receive stdin and hang indefinitely, probably due to a | ||
# strictness issue of the monads involved. | ||
# | ||
# The purpose of this script is to provide a hack, hidding the plumbing inside a | ||
# bash script to avoid depending on the pipe from Haskell. The parameter | ||
# following `--` is taken as the input for cardano-address. The rest of the | ||
# arguments are propagated as-is. | ||
# | ||
# In order to use cardano-address in property testing from Haskell, you must | ||
# install this script on your path. | ||
|
||
args=() | ||
|
||
while [ $# -gt 0 ]; do | ||
case "$1" in | ||
"--") | ||
shift | ||
break 2 | ||
;; | ||
*) | ||
args+=("$1") | ||
shift | ||
;; | ||
esac | ||
done | ||
|
||
if [ -t 0 ]; then | ||
printf '%s\n' "$1" | ||
else | ||
cat - | ||
fi | cardano-address "${args[@]}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
{-# LANGUAGE DerivingStrategies #-} | ||
{-# LANGUAGE ImportQualifiedPost #-} | ||
{-# LANGUAGE RankNTypes #-} | ||
{-# LANGUAGE RecordWildCards #-} | ||
{-# LANGUAGE TypeFamilies #-} | ||
|
||
module Tokenomia.CardanoApi.Fees | ||
( HasDatumHash(..) | ||
, calculateDefaultMinimumUTxOFromValue | ||
, calculateMinimumUTxOFromValue | ||
, calculateDefaultMinimumUTxOFromAssetId | ||
, calculateMinimumUTxOFromAssetId | ||
, utxoEntrySize | ||
) | ||
where | ||
|
||
import Cardano.Api | ||
( ShelleyBasedEra(..) | ||
, AssetId(..) | ||
, Value | ||
, Lovelace(..) | ||
, selectLovelace | ||
, valueFromList | ||
) | ||
|
||
import Cardano.Api.Shelley | ||
( ProtocolParameters(..) | ||
, calcMinimumDeposit | ||
, lovelaceToValue | ||
, toMaryValue | ||
) | ||
|
||
import Cardano.Ledger.Val qualified | ||
as Value ( size ) | ||
|
||
import Tokenomia.CardanoApi.Value ( unLovelace ) | ||
import Tokenomia.CardanoApi.PParams ( defaultCalculateMinimumUTxOParams ) | ||
|
||
|
||
data HasDatumHash | ||
= NoDatumHash | ||
| WithDatumHash | ||
deriving stock (Show) | ||
|
||
-- | Utxo entry size calculation | ||
utxoEntrySize :: Value -> HasDatumHash -> Integer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. la maj vasil introduit les inline datum qui peuvent impacter ce calcul |
||
utxoEntrySize value datum = | ||
utxoEntrySizeWithoutVal + Value.size (toMaryValue value) + datumHashSize datum | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tu mets explicitement toMaryValue, y a-t-il une notion de rétrocompatibilité à prendre en compte également ? quel impact pour les futurs versions ? faudra-t-il changer cette fonction ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This calculation is specific to the Alonzo era, as described in : https://github.com/input-output-hk/cardano-ledger/blob/2c203ead68913d660389f04a705c734c155c2a35/doc/explanations/min-utxo-alonzo.rst The drawback of patching fees or minUTxO calculations is that those pieces of code are very unstable and will require maintenance. The only intent is to avoid generating a valid |
||
where | ||
datumHashSize :: HasDatumHash -> Integer | ||
datumHashSize NoDatumHash = 0 | ||
datumHashSize WithDatumHash = 10 | ||
|
||
utxoEntrySizeWithoutVal :: Integer | ||
utxoEntrySizeWithoutVal = 27 | ||
Comment on lines
+50
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cardano est très "paramétrisable" dans le sens où on peut jouer avec les protocol-parameters sans avoir à sortir une nouvelle version du noeud, ces utxo et datumhash sizes font-elles parti de ces fameux paramètres ? le cas échéant, faut-il regrouper dans un fichier de conf les paramètres ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
|
||
|
||
-- | Calculate minimumUTxO simply from Value instead of TxOut | ||
calculateMinimumUTxOFromValue :: | ||
forall era. | ||
ShelleyBasedEra era | ||
-> Value | ||
-> HasDatumHash | ||
-> ProtocolParameters | ||
-> Maybe Value | ||
calculateMinimumUTxOFromValue era value datumHash ProtocolParameters{..} = | ||
lovelaceToValue <$> | ||
case era of | ||
ShelleyBasedEraShelley -> protocolParamMinUTxOValue | ||
ShelleyBasedEraAllegra -> calculateMinimumUTxOAllegraMary | ||
ShelleyBasedEraMary -> calculateMinimumUTxOAllegraMary | ||
ShelleyBasedEraAlonzo -> calculateMinimumUTxOAlonzo | ||
where | ||
calculateMinimumUTxOAllegraMary :: Maybe Lovelace | ||
calculateMinimumUTxOAllegraMary = | ||
calcMinimumDeposit value | ||
<$> protocolParamMinUTxOValue | ||
|
||
calculateMinimumUTxOAlonzo :: Maybe Lovelace | ||
calculateMinimumUTxOAlonzo = | ||
(Lovelace (utxoEntrySize value datumHash) *) | ||
<$> protocolParamUTxOCostPerWord | ||
Comment on lines
+68
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. si je comprends bien on devra mettre ça à jour à chaque fois qu'on entre dans une nouvelle era qui touche à ce calcul ? |
||
|
||
-- | Calculate minimumUTxO with default protocol parameters from a Value | ||
calculateDefaultMinimumUTxOFromValue :: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. quelle est la motivation derrière ces fonctions default ? ou plutôt pourquoi avons-nous besoin des fonctions "non default" ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
forall era. | ||
ShelleyBasedEra era -> Value -> HasDatumHash -> Maybe Value | ||
calculateDefaultMinimumUTxOFromValue era value datumHash = | ||
calculateMinimumUTxOFromValue era value datumHash $ | ||
defaultCalculateMinimumUTxOParams era | ||
|
||
-- | Calculate minimumUTxO for a singleton Value from AssetId | ||
calculateMinimumUTxOFromAssetId :: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ce cas particulier est-il nécessaire ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the simplest way to call the calculation in the validatePrivateSale PrivateSale{..} =
let proportions = TranchesProportions $ proportion <$> tranchesProperties
in
liftEither $ do
ε <- calculateDefaultMinimumUTxOFromAssetClass assetClass |
||
forall era. | ||
ShelleyBasedEra era | ||
-> AssetId | ||
-> ProtocolParameters | ||
-> Maybe Integer | ||
calculateMinimumUTxOFromAssetId era assetId parameters = | ||
let value = valueFromList [(assetId, 1)] | ||
in | ||
unLovelace . selectLovelace <$> | ||
calculateMinimumUTxOFromValue era value NoDatumHash parameters | ||
|
||
-- | Calculate minimumUTxO with default protocol parameters from AssetId | ||
calculateDefaultMinimumUTxOFromAssetId :: | ||
forall era. | ||
ShelleyBasedEra era -> AssetId -> Maybe Integer | ||
calculateDefaultMinimumUTxOFromAssetId era assetId = | ||
calculateMinimumUTxOFromAssetId era assetId $ | ||
defaultCalculateMinimumUTxOParams era |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{-# LANGUAGE DerivingStrategies #-} | ||
|
||
module Tokenomia.CardanoApi.FromPlutus.Error | ||
( FromPlutusError(..) | ||
) where | ||
|
||
|
||
data FromPlutusError | ||
= PlutusCurrencySymbolNotPolicyId | ||
| PlutusTokenNameNotAssetName | ||
| PlutusAssetClassNotAssetId | ||
deriving stock (Show) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
{-# LANGUAGE ImportQualifiedPost #-} | ||
{-# LANGUAGE TupleSections #-} | ||
|
||
module Tokenomia.CardanoApi.FromPlutus.Value | ||
( currencySymbolAsPolicyId | ||
, tokenNameAsAssetName | ||
, assetClassAsAssetId | ||
, fromPlutusValue | ||
) where | ||
|
||
import Data.Either.Combinators ( maybeToRight ) | ||
import Data.Functor ( (<&>) ) | ||
import Tokenomia.Common.Data.Either.Extra ( toEither ) | ||
|
||
import Cardano.Api | ||
( PolicyId | ||
, AssetName | ||
, AssetId(..) | ||
, AsType(..) | ||
, Quantity(..) | ||
, Value | ||
, deserialiseFromRawBytes | ||
, valueFromList | ||
) | ||
|
||
import PlutusTx.Builtins ( fromBuiltin ) | ||
import Plutus.V1.Ledger.Ada ( adaSymbol, adaToken ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. on a pas mal de références à Plutus.V1, je ne me rends pas compte de ce que va apporter Plutus.V2 comme modifications. Je crois que V2 arrive avec Vasil si je ne me trompe pas, à moins que ce soit déjà déployé. |
||
import Plutus.V1.Ledger.Value qualified | ||
as Plutus ( Value ) | ||
import Plutus.V1.Ledger.Value | ||
( AssetClass(..) | ||
, CurrencySymbol(..) | ||
, TokenName(..) | ||
, flattenValue | ||
, assetClass | ||
) | ||
|
||
import Tokenomia.CardanoApi.FromPlutus.Error | ||
( FromPlutusError(..) ) | ||
|
||
|
||
-- | Convert a CurrencySymbol to a PolicyId | ||
currencySymbolAsPolicyId :: CurrencySymbol -> Either FromPlutusError PolicyId | ||
currencySymbolAsPolicyId (CurrencySymbol x) = | ||
maybeToRight PlutusCurrencySymbolNotPolicyId $ | ||
deserialiseFromRawBytes AsPolicyId (fromBuiltin x) | ||
|
||
-- | Convert a TokenName to an AssetName | ||
tokenNameAsAssetName :: TokenName -> Either FromPlutusError AssetName | ||
tokenNameAsAssetName (TokenName x) = | ||
maybeToRight PlutusTokenNameNotAssetName $ | ||
deserialiseFromRawBytes AsAssetName (fromBuiltin x) | ||
|
||
-- | Convert an AssetClass to an AssetId | ||
assetClassAsAssetId :: AssetClass -> Either FromPlutusError AssetId | ||
assetClassAsAssetId (AssetClass (cs, tn)) | ||
| cs == adaSymbol = | ||
toEither (tn == adaToken) | ||
PlutusAssetClassNotAssetId | ||
AdaAssetId | ||
| otherwise = | ||
AssetId | ||
<$> currencySymbolAsPolicyId cs | ||
<*> tokenNameAsAssetName tn | ||
|
||
-- | Convert a Plutus Value to a Cardano.Api Value | ||
fromPlutusValue :: Plutus.Value -> Either FromPlutusError Value | ||
fromPlutusValue value = | ||
valueFromList <$> sequence (fromPlutusSingleton <$> flattenValue value) | ||
where | ||
fromPlutusSingleton (cs, tn, x) = | ||
assetClassAsAssetId (assetClass cs tn) <&> (, Quantity x) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{-# LANGUAGE ImportQualifiedPost #-} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. besoin de faire un point sur la gestion de ces paramètres de manière générale dans tokenomia |
||
{-# LANGUAGE RankNTypes #-} | ||
{-# LANGUAGE TypeFamilies #-} | ||
|
||
module Tokenomia.CardanoApi.PParams | ||
( defaultCalculateMinimumUTxOParams | ||
, withCalculateMinimumUTxOParams | ||
) where | ||
|
||
import Cardano.Api ( ShelleyBasedEra(..), fromLedgerPParams ) | ||
import Cardano.Api.Shelley ( ProtocolParameters, ShelleyLedgerEra ) | ||
import Cardano.Ledger.Coin ( Coin (..) ) | ||
import Cardano.Ledger.Core ( PParams ) | ||
import Cardano.Ledger.Alonzo.PParams ( PParams'(..) ) | ||
import Cardano.Ledger.Shelley.PParams ( PParams'(..) ) | ||
import Data.Default ( def ) | ||
|
||
|
||
-- | Update the right parameters necessary to calculateMinimumUTxO | ||
withCalculateMinimumUTxOParams :: | ||
forall era. | ||
Integer -> ShelleyBasedEra era -> PParams (ShelleyLedgerEra era) -> ProtocolParameters | ||
withCalculateMinimumUTxOParams n era pparams = | ||
fromLedgerPParams era $ updateWith (Coin n) pparams | ||
where | ||
updateWith = | ||
case era of | ||
ShelleyBasedEraShelley -> (\x up -> up {_minUTxOValue = x}) | ||
ShelleyBasedEraAllegra -> (\x up -> up {_minUTxOValue = x}) | ||
ShelleyBasedEraMary -> (\x up -> up {_minUTxOValue = x}) | ||
ShelleyBasedEraAlonzo -> (\x up -> up {_coinsPerUTxOWord = x}) | ||
|
||
-- | Default parameters necessary to calculateMinimumUTxO | ||
defaultCalculateMinimumUTxOParams :: | ||
forall era. | ||
ShelleyBasedEra era -> ProtocolParameters | ||
defaultCalculateMinimumUTxOParams era = | ||
case era of | ||
ShelleyBasedEraShelley -> withCalculateMinimumUTxOParams 1000000 era def | ||
ShelleyBasedEraAllegra -> withCalculateMinimumUTxOParams 1000000 era def | ||
ShelleyBasedEraMary -> withCalculateMinimumUTxOParams 1000000 era def | ||
ShelleyBasedEraAlonzo -> withCalculateMinimumUTxOParams 34482 era def |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module Tokenomia.CardanoApi.Value | ||
( unLovelace | ||
, unQuantity | ||
) where | ||
|
||
import Cardano.Api | ||
( Lovelace(..) | ||
, Quantity(..) | ||
) | ||
|
||
|
||
unLovelace :: Lovelace -> Integer | ||
unLovelace (Lovelace l) = l | ||
|
||
unQuantity :: Quantity -> Integer | ||
unQuantity (Quantity l) = l | ||
Comment on lines
+12
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. je ne sais pas pour unQuantity mais il me semble que unLovelace existe déjà There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
module Tokenomia.Common.Aeson.AssetClass | ||
( assetClassFromJSON | ||
, assetClassToJSON | ||
) where | ||
|
||
import Control.Arrow ( (***) ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c'est quoi ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I should have used |
||
|
||
import Data.Aeson.Types ( Parser ) | ||
import Data.Aeson ( Value, object, withObject, (.:), (.=) ) | ||
import Data.String ( IsString(..) ) | ||
|
||
import Plutus.V1.Ledger.Value ( AssetClass(..), assetClass, toString ) | ||
|
||
|
||
-- | Alternative AssetClass Parser to the FromJSON instance | ||
assetClassFromJSON :: Value -> Parser AssetClass | ||
assetClassFromJSON = withObject "AssetClass" $ \o -> | ||
assetClass | ||
<$> (fromString <$> o .: "currencySymbol") | ||
<*> (fromString <$> o .: "tokenName") | ||
|
||
-- | Alternative AssetClass Value to the ToJSON instance | ||
assetClassToJSON :: AssetClass -> Value | ||
assetClassToJSON x = | ||
let (currencySymbol, tokenName) = (show *** toString) $ unAssetClass x | ||
in | ||
object | ||
[ "currencySymbol" .= currencySymbol | ||
, "tokenName" .= tokenName | ||
] | ||
Comment on lines
+18
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. les toJSON avec les lenses faisaient pas le taf ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
potentiellement remplacé complètement le binaire par l'intégration directe de la lib haskell https://github.com/input-output-hk/cardano-addresses
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, maybe with https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/gen/Gen/Cardano/Api/Typed.hs