Fluid Aquarium
tx3 protocol for FluidTokens Aquarium — babel fees and scheduled transactions on Cardano.
Status: WIP — This tx3 off-chain implementation is under testing and may not cover all edge cases yet.
Overview
Fluid Aquarium allows users to create "tanks" (UTxOs with ADA) that can be consumed by:
- Babel fee bots: Pay a user's transaction fees in exchange for native tokens at an oracle-determined rate
- Aquarium nodes: Execute scheduled transactions at a specified future time
Users can also stake FLDT tokens to register as Aquarium node operators.
Transactions
| Transaction | Description |
|---|---|
create_babel_tank | Create a tank for babel fee payments (ADA deposit + datum) |
create_scheduled_tank | Create a tank for scheduled transaction execution |
withdraw_tank | Reclaim ADA from an owned tank |
consume_oracle | Batcher consumes part of a tank's ADA, paying the owner in tokens at oracle rate |
execute_scheduled | Batcher executes a scheduled transaction after its execution time |
stake_fldt | Stake FLDT tokens to become an Aquarium node operator |
Important Considerations
- Tank creation is script-free:
create_babel_tankandcreate_scheduled_tankare plain payments with inline datums — no validators execute. - Oracle validation:
consume_oracleuses a withdrawal-based oracle (0 ADA withdrawal with redeemer). The oracle redeemer currently supports Charli3 price feeds. - Known tx3 limitation: The withdrawal redeemer in
consume_oracleis defined but tx3 does NOT generate the reward redeemer in the witness set (the withdrawal body entry is correct). This may require manual patching. - Raw CBOR datums: Tank creation transactions use raw CBOR for the datum (
tank_datum_cbor) because theTankDatumtype contains nested lists and optional types that are complex to pass as parameters. - Reference inputs ordering:
consume_oraclerelies on multiple reference inputs (oracle provider, oracle contract, staker, parameters NFT, tank ref script) — their indices in the transaction must match the redeemer fields. - Staker redeemer:
stake_fldtuses a raw CBOR redeemer (staker_redeemer_cbor) due to tx3 limitations on custom types as parameters.
Caller Preparation
Several values must be prepared off-chain before invoking transactions:
create_babel_tank / create_scheduled_tank
tank_datum_cbor: Bytes— The full tank datum must be serialized as raw CBOR by the caller. TheTankDatumtype contains nested lists, optional types, and on-chainAddressstructures too complex to pass as individual parameters.
consume_oracle
This transaction requires extensive off-chain data:
- Oracle price data:
oracle_price,oracle_denominator,oracle_valid_from,oracle_valid_to,oracle_token_policy,oracle_token_name— queried from the Charli3 oracle datum on-chain. - Reference input indices:
input_tank_idx,oracle_idx,ref_params_idx,oracle_provider_idx,paying_token_idx— must match the actual ordering of inputs in the built transaction. - Payment calculation:
payment_ada,payment_token_qty,tank_return_ada,dest_ada— computed from the oracle price and tank contents.
execute_scheduled
batcher_addr_cbor: Bytes— The batcher's on-chainAddressmust be CBOR-encoded externally (tx3 cannot construct PlutusAddresstypes as params).signer_hash: Bytes— The batcher's staking key hash (not payment key). tx3'ssignersblock only extracts payment keys.
stake_fldt
staker_redeemer_cbor: Bytes— The staker redeemer must be serialized as raw CBOR due to tx3 limitations on custom types as parameters.signer_hash: Bytes— The user's staking key hash (same reason as above).
tx3 Limitations
Several tx3 language limitations affect this protocol. The most critical: the withdrawal redeemer is not generated in the witness set, blocking consume_oracle from executing on-chain without CBOR post-processing. For the full list, see investigacion/tx3-limitations-aquarium.md.
Smart Contracts
- PlutusV3 (Aiken v1.1.9)
- Source: FluidTokens/ft-cardano-aquarium-sc
fluid-aquarium
Published by
@fluidtokens