🛠️Developer Manual

Overview

Decentralized AMM price feeds are exposed by the Cerra AMM smart contract. Each time Cerra AMM users swap tokens in the pool, pool price is updated and becomes instantly available to be consumed by another smart contract.

At Cerra AMM smart contract, each pool is represented as a separate UTXO, carrying information about its liquidity and price in the inline datum:

https://preprod.cardanoscan.io/datumInspector?datum=d8799fd8799f4040ffd8799f581c46f987f7ed1886ba771b077c3ed5bbf3df158f54e0e3fa88d3d1e46e46744345525241ff1a02805e6300d87a80a647616d6f756e74411b000000045697dafa47616d6f756e74421a00018222467072696365411a0050f370467072696365421b029daa91a9add8074a707265636973696f6e410c4a707265636973696f6e420cff

This inline datum can be referenced by any other smart contract as a reference input, this way avoiding concurrency (as we are not consuming, but rather referencing the UTXO). It can be referenced by an infinite amount of smart contracts at the same time.

Once added to the smart contract transaction as a reference input, the price information within the input can be safely used (after validation of course), and smart contract is able to use this information in its business logic.

AMM Mainet smart contract address:

addr1zyl8u7cw93g99g2e68cq3k27ad7rd8p6yy3yg9vesgahrus0pqnxu0fg7wvwgjtgzvg6lg6avzczmwf84aclygrvlkhq2a0paj

Preprod Testnet AMM smart contract address:

addr_test1zpw9z4x40hqxw20aydveps33x67n894a9dtfmfe2f7s37ywwrt5fks9dqdndm86fwka3arsz6f0af8y8hplqtzj98ujs46xwr0

Pool UTXO list:

https://app.cerra.io/oracles

Datum structure:

Price information structure:

Implementation

Follow this step by step guide to utilize Cerra Decentralized AMM price feeds in your smart contracts, starting with the off-chain part:

Off-chain:

  1. Find the latest specific pool UTXO in the AMM smart contract. Remember, that each UTXO represents different pool (token pair):

  1. Take UTXO hash and pass it as reference input to your smart contract transaction (cardano-cli example):

cardano-cli transaction build-raw

--babbage-era

...

--read-only-tx-in-reference 0f341e1ad85838939f413a33823f7f96b9136bcfa08cfcf358dc735ef541771a#0

...

--fee 500000

  1. That’s it, we are done with the off-chain part! Now your smart contract has the needed token price information.

On-chain (Plutus example):

  1. Define price feed datum structure:

data PriceDatum = PriceDatum

{ pdData :: Map BuiltinByteString PlutusTx.BuiltinData

}

deriving stock (Haskell.Show)

PlutusTx.makeIsDataIndexed ‘’PriceDatum [(‘PriceDatum , 0)]

PlutusTx.makeLift ‘’PriceDatum

2. Define helper function, which will retrieve the reference input datum:

mustFindScriptDatum :: (UnsafeFromData d) => TxOut -> TxInfo -> d

mustFindScriptDatum o info = case txOutDatum o of

OutputDatum dat -> PlutusTx.unsafeFromBuiltinData (getDatum dat)

OutputDatumHash dh -> case findDatum dh info of

Just (Datum dat) -> PlutusTx.unsafeFromBuiltinData dat

_ -> error ()

NoOutputDatum -> error ()

3. Retrieve the datum from previously passed reference input:

info :: TxInfo

info = scriptContextTxInfo context

txReferenceInputs :: [TxInInfo]

txReferenceInputs = txInfoReferenceInputs info

priceInput = txInInfoResolved (txReferenceInputs !! 0)

priceDatum = mustFindScriptDatum @PriceDatum priceInput info

data = pdData priceDatum

  1. Read the needed price information fields like this:

amountA = Map.lookup “amountA” data

priceB = Map.lookup “priceB ” data

That’s it! You successfully retrieved token pair price information on-chain.

Timestamps

The very last field of the price information in the Datum is a timestamp. Timestamp represents the time price information was issued. Based on this field, smart contract can validate if currently consumed price reference UTXO is still relevant. Timestamp is expressed as POSIXTime divided by 1000, meaning it represents seconds.

Additional information

Have in mind that this is the simplest possible implementation with the purpose of showing how to retrieve the Cerra Decentralized AMM price feed information in your smart contract. It is by no means safe to use this example in production.

In order to prove UTXO authenticity and validity, it is needed to at least:

  • Validate the authenticity of the Policy ID of the NFT asset which is present at reference input.

  • Validate that both assets (Policy ID + Token Name) are the ones you are expecting. Asset information is provided in the Datum.

  • Ensure that you are using latest UTXO for the specific pool, as any UTXO from the past can also be passed as valid reference input. In the smart contract, validate the 'timestamp' Datum field, based on your usecase.

If you consider integrating Cerra Decentralized AMM price feeds to your project, have any feedback to share with us, or need any help, please contact us at admin@cerra.io

Last updated