charli3_dendrite 1.5.14.dev3__tar.gz → 1.5.15.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/PKG-INFO +1 -1
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/pyproject.toml +2 -2
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/cardanoswaps.py +2 -2
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/chadswap.py +2 -2
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/ob_base.py +32 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/saturnswap.py +7 -4
- charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/__init__.py +4 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/constants.py +18 -0
- charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/transactions/__init__.py +1 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/borrow.py +1 -8
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/builder.py +76 -24
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/common.py +37 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/lender_bond.py +58 -25
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/loan_action.py +2 -4
- charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_action.py +364 -0
- charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_cancel.py +238 -0
- charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_create.py +441 -0
- charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_edit.py +297 -0
- charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_terms.py +220 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/redeemers.py +136 -9
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/resolve.py +156 -5
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/transactions/base.py +4 -0
- charli3_dendrite-1.5.14.dev3/src/charli3_dendrite/lending/fluidtokens_v4/__init__.py +0 -1
- charli3_dendrite-1.5.14.dev3/src/charli3_dendrite/lending/fluidtokens_v4/transactions/__init__.py +0 -1
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/LICENSE +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/README.md +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/backend_base.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/blockfrost/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/blockfrost/models.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/dbsync/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/dbsync/models.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/ogmios_kupo/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/ogmios_kupo/models.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/backend/utils.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dataclasses/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dataclasses/datums.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dataclasses/models.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/amm_base.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/amm_types.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/cswap.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/dano.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/minswap.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/muesli.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/multi_asset.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/spectrum.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/splash.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/sundae.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/sundae_v4.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/sundae_v4_deployments.json +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/vyfi.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/amm/wingriders.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/core/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/core/base.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/core/errors.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/axo.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/djed.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/dexs/ob/geniusyield.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/base.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/constants.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/datums.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/loader.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/market.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/math.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/aggregator.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/aggregator_datums.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/deployments.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/forward.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/leaves.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/locator.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/lp_pricing.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/recipes.json +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/redeemer.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/reproduce.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/oracles/structured_datums.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/state.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/_common.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/build.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/builder.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/context.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/create_loan.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/datum_synth.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/increase_loan.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/loan_ids.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/modify_collateral.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/oracle_redeemer.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/oracle_synth.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/redeemers.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/repay.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/topup_withdraw.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/danogo/transactions/verify.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/constants.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/datums.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/loader.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/market.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/math.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/oracles/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/oracles/feeds.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/oracles/fluid_api.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/oracles/witness.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/state.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/_common.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/borrow.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/borrow_terms.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/builder.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/change_collateral.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/context.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/datum_synth.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/lend.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/pool.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/recast.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/redeemers.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/repay.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/request.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/resolve.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens/transactions/utxos.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/datums.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/indexing.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/loader.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/state.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/change_collateral.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/loan_terms.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/oracle.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/recast.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/repay.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/math.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/oracles/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/oracles/charli3.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/oracles/dex_pooled.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/oracles/fluid.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/oracles/models.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/oracles/orcfax.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/oracles/qtoken.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/plutus.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/registry.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/transactions/__init__.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/transactions/infra.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/transactions/snapshot.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/lending/units.py +0 -0
- {charli3_dendrite-1.5.14.dev3 → charli3_dendrite-1.5.15.dev1}/src/charli3_dendrite/utility.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "charli3_dendrite"
|
|
3
|
-
version = "1.5.
|
|
3
|
+
version = "1.5.15-dev1"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["Elder Millenial <eldermillenial@protonmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -50,7 +50,7 @@ module = ["pycardano", "pycardano.*", "dotenv", "nox", "uplc", "uplc.*"]
|
|
|
50
50
|
ignore_missing_imports = true
|
|
51
51
|
|
|
52
52
|
[tool.bumpversion]
|
|
53
|
-
current_version = "1.5.
|
|
53
|
+
current_version = "1.5.15-dev1"
|
|
54
54
|
parse = """(?x)
|
|
55
55
|
(?P<major>\\d+)\\.
|
|
56
56
|
(?P<minor>\\d+)\\.
|
|
@@ -42,6 +42,7 @@ from charli3_dendrite.dexs.ob.ob_base import AbstractOrderState
|
|
|
42
42
|
from charli3_dendrite.dexs.ob.ob_base import BuyOrderBook
|
|
43
43
|
from charli3_dendrite.dexs.ob.ob_base import OrderBookOrder
|
|
44
44
|
from charli3_dendrite.dexs.ob.ob_base import SellOrderBook
|
|
45
|
+
from charli3_dendrite.dexs.ob.ob_base import fill_within_budget
|
|
45
46
|
from charli3_dendrite.utility import asset_to_value
|
|
46
47
|
|
|
47
48
|
# v2 one-way beacon minting policy id (also stored verbatim in the datum's
|
|
@@ -973,8 +974,7 @@ class CardanoSwapsOrderBook(AbstractOrderBookState):
|
|
|
973
974
|
for order in book:
|
|
974
975
|
state = order.state
|
|
975
976
|
|
|
976
|
-
order_out,
|
|
977
|
-
order_in, _ = state.get_amount_in(order_out)
|
|
977
|
+
order_out, order_in = fill_within_budget(state, in_remaining)
|
|
978
978
|
|
|
979
979
|
# Stop once the remaining budget cannot satisfy a meaningful fill.
|
|
980
980
|
if order_out.quantity() <= 0 or order_in.quantity() <= 0:
|
|
@@ -32,6 +32,7 @@ from charli3_dendrite.dexs.ob.ob_base import AbstractOrderState
|
|
|
32
32
|
from charli3_dendrite.dexs.ob.ob_base import BuyOrderBook
|
|
33
33
|
from charli3_dendrite.dexs.ob.ob_base import OrderBookOrder
|
|
34
34
|
from charli3_dendrite.dexs.ob.ob_base import SellOrderBook
|
|
35
|
+
from charli3_dendrite.dexs.ob.ob_base import fill_within_budget
|
|
35
36
|
from charli3_dendrite.utility import asset_to_value
|
|
36
37
|
|
|
37
38
|
|
|
@@ -719,8 +720,7 @@ class ChadSwapOrderBook(AbstractOrderBookState):
|
|
|
719
720
|
for order in book:
|
|
720
721
|
state = order.state
|
|
721
722
|
|
|
722
|
-
order_out,
|
|
723
|
-
order_in, _ = state.get_amount_in(order_out)
|
|
723
|
+
order_out, order_in = fill_within_budget(state, in_remaining)
|
|
724
724
|
|
|
725
725
|
# Stop if remaining budget cannot satisfy the smallest meaningful fill.
|
|
726
726
|
if order_out.quantity() <= 0 or order_in.quantity() <= 0:
|
|
@@ -242,6 +242,38 @@ class AbstractOrderState(AbstractPairState):
|
|
|
242
242
|
return values
|
|
243
243
|
|
|
244
244
|
|
|
245
|
+
def fill_within_budget(
|
|
246
|
+
state: AbstractOrderState,
|
|
247
|
+
budget: Assets,
|
|
248
|
+
precise: bool = True,
|
|
249
|
+
) -> tuple[Assets, Assets]:
|
|
250
|
+
"""The largest fill of ``state`` whose input fits ``budget``: ``(out, in)``.
|
|
251
|
+
|
|
252
|
+
An order prices the output a budget buys and then the input that output costs,
|
|
253
|
+
each rounded up, so on a partial fill the input can exceed the budget. The output
|
|
254
|
+
is then shrunk to the largest amount whose input still fits (zero when not even
|
|
255
|
+
one unit fits).
|
|
256
|
+
"""
|
|
257
|
+
order_out, _ = state.get_amount_out(budget, precise=precise)
|
|
258
|
+
order_in, _ = state.get_amount_in(order_out, precise=precise)
|
|
259
|
+
if order_in.quantity() <= budget.quantity():
|
|
260
|
+
return order_out, order_in
|
|
261
|
+
unit = order_out.unit()
|
|
262
|
+
low, high = 0, order_out.quantity() - 1
|
|
263
|
+
while low < high:
|
|
264
|
+
mid = (low + high + 1) // 2
|
|
265
|
+
need, _ = state.get_amount_in(Assets(**{unit: mid}), precise=precise)
|
|
266
|
+
if need.quantity() <= budget.quantity():
|
|
267
|
+
low = mid
|
|
268
|
+
else:
|
|
269
|
+
high = mid - 1
|
|
270
|
+
if low == 0:
|
|
271
|
+
return Assets(**{unit: 0}), Assets(**{budget.unit(): 0})
|
|
272
|
+
order_out = Assets(**{unit: low})
|
|
273
|
+
order_in, _ = state.get_amount_in(order_out, precise=precise)
|
|
274
|
+
return order_out, order_in
|
|
275
|
+
|
|
276
|
+
|
|
245
277
|
class OrderBookOrder(DendriteBaseModel):
|
|
246
278
|
"""Represents an order in the order book."""
|
|
247
279
|
|
|
@@ -40,6 +40,7 @@ from charli3_dendrite.dexs.ob.ob_base import AbstractOrderState
|
|
|
40
40
|
from charli3_dendrite.dexs.ob.ob_base import BuyOrderBook
|
|
41
41
|
from charli3_dendrite.dexs.ob.ob_base import OrderBookOrder
|
|
42
42
|
from charli3_dendrite.dexs.ob.ob_base import SellOrderBook
|
|
43
|
+
from charli3_dendrite.dexs.ob.ob_base import fill_within_budget
|
|
43
44
|
from charli3_dendrite.utility import asset_to_value
|
|
44
45
|
|
|
45
46
|
# SaturnSwap charges an on-chain taker fee on every fill that is NOT co-signed by
|
|
@@ -1361,8 +1362,11 @@ class SaturnSwapOrderBook(AbstractOrderBookState):
|
|
|
1361
1362
|
if state is None:
|
|
1362
1363
|
continue
|
|
1363
1364
|
|
|
1364
|
-
order_out,
|
|
1365
|
-
|
|
1365
|
+
order_out, order_in = fill_within_budget(
|
|
1366
|
+
state,
|
|
1367
|
+
in_remaining,
|
|
1368
|
+
precise=precise,
|
|
1369
|
+
)
|
|
1366
1370
|
|
|
1367
1371
|
if order_out.quantity() <= 0 or order_in.quantity() <= 0:
|
|
1368
1372
|
break
|
|
@@ -1451,8 +1455,7 @@ class SaturnSwapOrderBook(AbstractOrderBookState):
|
|
|
1451
1455
|
if state is None:
|
|
1452
1456
|
continue
|
|
1453
1457
|
|
|
1454
|
-
order_out,
|
|
1455
|
-
order_in, _ = state.get_amount_in(order_out)
|
|
1458
|
+
order_out, order_in = fill_within_budget(state, in_remaining)
|
|
1456
1459
|
|
|
1457
1460
|
if order_out.quantity() <= 0 or order_in.quantity() <= 0:
|
|
1458
1461
|
break
|
|
@@ -11,6 +11,10 @@ The lender-manager spend script is not listed in the config datum: pools opt int
|
|
|
11
11
|
by pointing ``lender_bond_address`` at it, and it ships as a constant here. Its own
|
|
12
12
|
action scripts are listed in the lender-manager config datum, held with a separate
|
|
13
13
|
config NFT.
|
|
14
|
+
|
|
15
|
+
The pool manager's owner-check scripts are not listed either: they are parameters of
|
|
16
|
+
the pool-manager policy, so they change only with a new pool-manager policy, which
|
|
17
|
+
the config datum would name.
|
|
14
18
|
"""
|
|
15
19
|
|
|
16
20
|
from __future__ import annotations
|
|
@@ -69,6 +73,20 @@ LOCKED_BORROWER_MANAGER_SPEND_SKH = (
|
|
|
69
73
|
# Not carried by the config datum (see the module docstring).
|
|
70
74
|
LENDER_MANAGER_SPEND_SKH = "6743f4b69446b4e066cfb89daa3d01ef041b6d2646968993be4cec09"
|
|
71
75
|
|
|
76
|
+
# The pool manager's owner checks for a pool edit and a pool cancel: the
|
|
77
|
+
# ``pm_edit_pool`` and ``pm_cancel_pool_manager`` validators of
|
|
78
|
+
# ``ft-cardano-loans-v4`` at ``04b6e70``, applied to the config NFT, the pool spend
|
|
79
|
+
# script, the pool policy and the smart-tokens spend script, and applied in turn to
|
|
80
|
+
# :data:`POOL_MANAGER_POLICY`. That build pairs the i-th spent pool with the i-th
|
|
81
|
+
# spent pool manager by input position; ``a8bb3f4d`` pairs them by NFT and hashes
|
|
82
|
+
# differently.
|
|
83
|
+
POOL_MANAGER_EDIT_POOL_ACTION_SKH = (
|
|
84
|
+
"df8247f95cf81bf662c38a95f43851022a58f1f0fcbb7b453544afae"
|
|
85
|
+
)
|
|
86
|
+
POOL_MANAGER_CANCEL_ACTION_SKH = (
|
|
87
|
+
"e39f6aac5e71c42edc7e190456483086dfdd94c73c0e352234cc3d1b"
|
|
88
|
+
)
|
|
89
|
+
|
|
72
90
|
# Plutus ``Credential``: ``ScriptCredential`` is constructor alternative 1 (tag 122).
|
|
73
91
|
_SCRIPT_CREDENTIAL_TAG = 122
|
|
74
92
|
|
charli3_dendrite-1.5.15.dev1/src/charli3_dendrite/lending/fluidtokens_v4/transactions/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""FluidTokens V4 transaction builders: borrower and lender actions."""
|
|
@@ -78,6 +78,7 @@ from charli3_dendrite.lending.fluidtokens_v4.transactions.common import ledger_o
|
|
|
78
78
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import loan_address
|
|
79
79
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import min_ada
|
|
80
80
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import out_ref_of
|
|
81
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import pool_nft_name
|
|
81
82
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import script_hash_of
|
|
82
83
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import (
|
|
83
84
|
withdraw_redeemer_position,
|
|
@@ -222,14 +223,6 @@ def priced_sides(
|
|
|
222
223
|
)
|
|
223
224
|
|
|
224
225
|
|
|
225
|
-
def pool_nft_name(pool: Utxo) -> bytes:
|
|
226
|
-
"""The name of the one pool NFT a pool UTxO holds."""
|
|
227
|
-
names = [n for p, n, q in pool.assets if p == c.POOL_POLICY and q == 1]
|
|
228
|
-
if len(names) != 1:
|
|
229
|
-
raise ValueError("pool UTxO must hold exactly one pool NFT")
|
|
230
|
-
return bytes.fromhex(names[0])
|
|
231
|
-
|
|
232
|
-
|
|
233
226
|
@dataclass(frozen=True)
|
|
234
227
|
class PoolBorrow:
|
|
235
228
|
"""A borrow from one pool: how much, against which collateral option.
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"""FluidTokens V4 implementation of the lending transaction seam.
|
|
2
2
|
|
|
3
3
|
``resolve_snapshot`` covers a single loan or pool from :class:`ActionParams`; several
|
|
4
|
-
pools or loans in one transaction
|
|
5
|
-
directly and go through
|
|
4
|
+
pools or loans in one transaction, a pool create, and an edit of a pool's terms
|
|
5
|
+
resolve through the snapshots' ``from_backend`` directly and go through
|
|
6
|
+
:meth:`FluidTokensV4TxBuilder.contribute` the same way.
|
|
6
7
|
"""
|
|
7
8
|
|
|
8
9
|
from __future__ import annotations
|
|
9
10
|
|
|
11
|
+
from collections.abc import Callable
|
|
10
12
|
from typing import TYPE_CHECKING
|
|
11
|
-
from typing import cast
|
|
12
13
|
|
|
13
14
|
from charli3_dendrite.lending.fluidtokens_v4.datums import PoolDatum
|
|
14
15
|
from charli3_dendrite.lending.fluidtokens_v4.state import collateral_asset_unit
|
|
@@ -21,6 +22,25 @@ from charli3_dendrite.lending.fluidtokens_v4.transactions.change_collateral impo
|
|
|
21
22
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.change_collateral import (
|
|
22
23
|
build_change_collateral,
|
|
23
24
|
)
|
|
25
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.pool_cancel import (
|
|
26
|
+
PoolCancelSnapshot,
|
|
27
|
+
)
|
|
28
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.pool_cancel import (
|
|
29
|
+
build_pool_cancel,
|
|
30
|
+
)
|
|
31
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.pool_create import (
|
|
32
|
+
PoolCreateSnapshot,
|
|
33
|
+
)
|
|
34
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.pool_create import (
|
|
35
|
+
build_pool_create,
|
|
36
|
+
)
|
|
37
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.pool_edit import PoolEdit
|
|
38
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.pool_edit import (
|
|
39
|
+
PoolEditSnapshot,
|
|
40
|
+
)
|
|
41
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.pool_edit import (
|
|
42
|
+
build_pool_edit,
|
|
43
|
+
)
|
|
24
44
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.recast import RecastSnapshot
|
|
25
45
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.recast import build_recast
|
|
26
46
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.repay import RepaySnapshot
|
|
@@ -36,11 +56,21 @@ if TYPE_CHECKING:
|
|
|
36
56
|
from charli3_dendrite.lending.transactions.base import ActionParams
|
|
37
57
|
from charli3_dendrite.lending.transactions.snapshot import PoolActionSnapshot
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
LendingAction
|
|
42
|
-
|
|
43
|
-
|
|
59
|
+
# Each action's snapshot type and the function that adds it to a builder.
|
|
60
|
+
_ACTIONS: dict[
|
|
61
|
+
LendingAction,
|
|
62
|
+
tuple[type[PoolActionSnapshot], Callable[..., None]],
|
|
63
|
+
] = {
|
|
64
|
+
LendingAction.BORROW: (BorrowSnapshot, build_borrow),
|
|
65
|
+
LendingAction.REPAY: (RepaySnapshot, build_repay),
|
|
66
|
+
LendingAction.MODIFY_COLLATERAL: (
|
|
67
|
+
ChangeCollateralSnapshot,
|
|
68
|
+
build_change_collateral,
|
|
69
|
+
),
|
|
70
|
+
LendingAction.RECAST: (RecastSnapshot, build_recast),
|
|
71
|
+
LendingAction.POOL_CREATE: (PoolCreateSnapshot, build_pool_create),
|
|
72
|
+
LendingAction.POOL_EDIT: (PoolEditSnapshot, build_pool_edit),
|
|
73
|
+
LendingAction.POOL_CANCEL: (PoolCancelSnapshot, build_pool_cancel),
|
|
44
74
|
}
|
|
45
75
|
|
|
46
76
|
|
|
@@ -60,7 +90,7 @@ def _single(collateral: dict[str, int], action: LendingAction) -> tuple[str, int
|
|
|
60
90
|
|
|
61
91
|
|
|
62
92
|
class FluidTokensV4TxBuilder(AbstractLendingTxBuilder):
|
|
63
|
-
"""Build FluidTokens V4
|
|
93
|
+
"""Build FluidTokens V4 borrower and lender transactions."""
|
|
64
94
|
|
|
65
95
|
@classmethod
|
|
66
96
|
def protocol(cls) -> str:
|
|
@@ -69,8 +99,8 @@ class FluidTokensV4TxBuilder(AbstractLendingTxBuilder):
|
|
|
69
99
|
|
|
70
100
|
@classmethod
|
|
71
101
|
def supported_actions(cls) -> set[LendingAction]:
|
|
72
|
-
"""Borrow, repay, change collateral and
|
|
73
|
-
return set(
|
|
102
|
+
"""Borrow, repay, change collateral, recast, and pool create, edit, cancel."""
|
|
103
|
+
return set(_ACTIONS)
|
|
74
104
|
|
|
75
105
|
def resolve_snapshot(
|
|
76
106
|
self,
|
|
@@ -93,6 +123,11 @@ class FluidTokensV4TxBuilder(AbstractLendingTxBuilder):
|
|
|
93
123
|
- MODIFY_COLLATERAL: ``loan_utxo`` is the loan and ``collateral`` its one
|
|
94
124
|
``{unit: new amount}``; prices are fetched from the registry.
|
|
95
125
|
- RECAST: ``loan_utxo`` is the loan and ``amount`` the principal paid.
|
|
126
|
+
- POOL_EDIT: ``loan_utxo`` is the pool and ``amount`` the principal it gains
|
|
127
|
+
(negative withdraws); its terms are kept. ``actor_address`` owns the pool.
|
|
128
|
+
- POOL_CANCEL: ``loan_utxo`` is the pool; ``actor_address`` owns it.
|
|
129
|
+
- POOL_CREATE takes lender terms ``ActionParams`` cannot carry: resolve it
|
|
130
|
+
with ``PoolCreateSnapshot.from_backend``.
|
|
96
131
|
"""
|
|
97
132
|
if action == LendingAction.BORROW:
|
|
98
133
|
return self._resolve_borrow(backend, params)
|
|
@@ -123,6 +158,33 @@ class FluidTokensV4TxBuilder(AbstractLendingTxBuilder):
|
|
|
123
158
|
recasts=[(_out_ref(params.loan_utxo, "loan"), params.amount)],
|
|
124
159
|
borrower_address=params.actor_address,
|
|
125
160
|
)
|
|
161
|
+
if action == LendingAction.POOL_EDIT:
|
|
162
|
+
if not params.amount:
|
|
163
|
+
raise ValueError(
|
|
164
|
+
"POOL_EDIT moves principal: params.amount must be non-zero; edit "
|
|
165
|
+
"a pool's terms with PoolEditSnapshot.from_backend",
|
|
166
|
+
)
|
|
167
|
+
return PoolEditSnapshot.from_backend(
|
|
168
|
+
backend,
|
|
169
|
+
edits=[
|
|
170
|
+
PoolEdit(
|
|
171
|
+
_out_ref(params.loan_utxo, "pool"),
|
|
172
|
+
principal_change=params.amount,
|
|
173
|
+
),
|
|
174
|
+
],
|
|
175
|
+
lender_address=params.actor_address,
|
|
176
|
+
)
|
|
177
|
+
if action == LendingAction.POOL_CANCEL:
|
|
178
|
+
return PoolCancelSnapshot.from_backend(
|
|
179
|
+
backend,
|
|
180
|
+
pools=[_out_ref(params.loan_utxo, "pool")],
|
|
181
|
+
lender_address=params.actor_address,
|
|
182
|
+
)
|
|
183
|
+
if action == LendingAction.POOL_CREATE:
|
|
184
|
+
raise ValueError(
|
|
185
|
+
"POOL_CREATE needs lender terms ActionParams cannot carry; resolve it "
|
|
186
|
+
"with PoolCreateSnapshot.from_backend and contribute that snapshot",
|
|
187
|
+
)
|
|
126
188
|
raise ValueError(f"{self.protocol()} does not support action {action.value!r}")
|
|
127
189
|
|
|
128
190
|
def _resolve_borrow(
|
|
@@ -170,24 +232,14 @@ class FluidTokensV4TxBuilder(AbstractLendingTxBuilder):
|
|
|
170
232
|
params: ActionParams, # - the snapshot carries every amount
|
|
171
233
|
) -> None:
|
|
172
234
|
"""Add the action described by ``snapshot`` to ``tx_builder``."""
|
|
173
|
-
|
|
174
|
-
if expected is None:
|
|
235
|
+
if action not in _ACTIONS:
|
|
175
236
|
raise ValueError(
|
|
176
237
|
f"{self.protocol()} does not support action {action.value!r}",
|
|
177
238
|
)
|
|
239
|
+
expected, build = _ACTIONS[action]
|
|
178
240
|
if not isinstance(snapshot, expected):
|
|
179
241
|
raise TypeError(
|
|
180
242
|
f"{action.value} expects {expected.__name__}, "
|
|
181
243
|
f"got {type(snapshot).__name__}",
|
|
182
244
|
)
|
|
183
|
-
|
|
184
|
-
build_borrow(tx_builder, snapshot=cast(BorrowSnapshot, snapshot))
|
|
185
|
-
elif action == LendingAction.REPAY:
|
|
186
|
-
build_repay(tx_builder, snapshot=cast(RepaySnapshot, snapshot))
|
|
187
|
-
elif action == LendingAction.MODIFY_COLLATERAL:
|
|
188
|
-
build_change_collateral(
|
|
189
|
-
tx_builder,
|
|
190
|
-
snapshot=cast(ChangeCollateralSnapshot, snapshot),
|
|
191
|
-
)
|
|
192
|
-
else:
|
|
193
|
-
build_recast(tx_builder, snapshot=cast(RecastSnapshot, snapshot))
|
|
245
|
+
build(tx_builder, snapshot=snapshot)
|
|
@@ -15,13 +15,17 @@ from pycardano import min_lovelace
|
|
|
15
15
|
from pycardano import plutus_script_hash
|
|
16
16
|
from pycardano import script_hash as pycardano_script_hash
|
|
17
17
|
|
|
18
|
+
from charli3_dendrite.dataclasses.models import Assets
|
|
18
19
|
from charli3_dendrite.lending.fluidtokens.transactions._common import reward_address
|
|
19
20
|
from charli3_dendrite.lending.fluidtokens.transactions.utxos import Utxo
|
|
20
21
|
from charli3_dendrite.lending.fluidtokens_v4 import constants as c
|
|
21
22
|
from charli3_dendrite.lending.transactions.infra import EvalContext
|
|
22
23
|
from charli3_dendrite.lending.units import constr
|
|
24
|
+
from charli3_dendrite.utility import asset_to_value
|
|
23
25
|
|
|
24
26
|
if TYPE_CHECKING:
|
|
27
|
+
from pycardano import Datum
|
|
28
|
+
|
|
25
29
|
from charli3_dendrite.lending.fluidtokens_v4.datums import CollateralAsset
|
|
26
30
|
|
|
27
31
|
# Default validity window of a repay or recast. They owe their amount as of the
|
|
@@ -48,6 +52,39 @@ def min_ada(output: TransactionOutput) -> int:
|
|
|
48
52
|
return min_lovelace(EvalContext(last_block_slot=0), output=output)
|
|
49
53
|
|
|
50
54
|
|
|
55
|
+
def settled_min_ada(address: Address, assets: dict[str, int], datum: Datum) -> int:
|
|
56
|
+
"""The least ADA an output of ``assets`` and ``datum`` at ``address`` can hold.
|
|
57
|
+
|
|
58
|
+
That is the least lovelace amount that covers the min-ADA of the output holding
|
|
59
|
+
it: the coin's own encoding grows with the amount, so the minimum is iterated to
|
|
60
|
+
its fixed point. ``assets`` maps unit to quantity and excludes lovelace.
|
|
61
|
+
"""
|
|
62
|
+
lovelace = 0
|
|
63
|
+
while True:
|
|
64
|
+
output = TransactionOutput(
|
|
65
|
+
address,
|
|
66
|
+
asset_to_value(Assets(**{"lovelace": lovelace, **assets})),
|
|
67
|
+
datum=datum,
|
|
68
|
+
)
|
|
69
|
+
needed = min_ada(output)
|
|
70
|
+
if needed <= lovelace:
|
|
71
|
+
return lovelace
|
|
72
|
+
lovelace = needed
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def sole_nft_name(utxo: Utxo, policy: str, what: str) -> bytes:
|
|
76
|
+
"""The name of the one NFT of ``policy`` a ``what`` UTxO holds."""
|
|
77
|
+
names = [n for p, n, q in utxo.assets if p == policy and q == 1]
|
|
78
|
+
if len(names) != 1:
|
|
79
|
+
raise ValueError(f"{what} UTxO must hold exactly one {what} NFT")
|
|
80
|
+
return bytes.fromhex(names[0])
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def pool_nft_name(pool: Utxo) -> bytes:
|
|
84
|
+
"""The name of the one pool NFT a pool UTxO holds."""
|
|
85
|
+
return sole_nft_name(pool, c.POOL_POLICY, "pool")
|
|
86
|
+
|
|
87
|
+
|
|
51
88
|
def is_policy_wide(collateral: CollateralAsset) -> bool:
|
|
52
89
|
"""True if ``collateral`` names only a policy (any token under it)."""
|
|
53
90
|
return constr(collateral.maybe_asset_name)[0] == _NONE
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
"""The lender-bond output datum a V4
|
|
1
|
+
"""The lender-bond output datum a V4 pool commits to.
|
|
2
2
|
|
|
3
3
|
A pool commits only ``blake2b_256`` of the lender-bond output's inline datum. Pools
|
|
4
4
|
that send lender bonds to the lender manager commit a :class:`LenderManagerDatum`
|
|
5
5
|
whose fields all come from chain except two lender settings: the pool NFT name, the
|
|
6
6
|
pool's principal asset, the pool manager's owner authorization, and the stake
|
|
7
7
|
credential of the pool's lender-bond address, plus whether liquidations convert the
|
|
8
|
-
collateral to principal and the liquidation fee per mille.
|
|
9
|
-
by hashing each candidate against the commitment.
|
|
8
|
+
collateral to principal and the liquidation fee per mille. A pool create picks the
|
|
9
|
+
settings; a borrow recovers them by hashing each candidate against the commitment.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
+
import hashlib
|
|
14
15
|
from collections.abc import Iterator
|
|
15
16
|
|
|
16
17
|
import cbor2 # type: ignore[import-not-found]
|
|
@@ -32,19 +33,23 @@ _FALSE = RawPlutusData(cbor2.CBORTag(121, []))
|
|
|
32
33
|
# Plutus ``Credential.ScriptCredential`` is constructor alternative 1.
|
|
33
34
|
_SCRIPT_CREDENTIAL = 1
|
|
34
35
|
|
|
35
|
-
# A
|
|
36
|
-
|
|
36
|
+
# A fee per mille is 0 to 1000: the range this module's commitment search covers,
|
|
37
|
+
# and the range a pool create bounds its own fees to.
|
|
38
|
+
MAX_FEE_PER_MILLE = 1000
|
|
37
39
|
|
|
38
|
-
# The settings every lender-manager pool used when this module was written
|
|
39
|
-
# first so the common case needs a
|
|
40
|
-
|
|
40
|
+
# The settings every lender-manager pool used when this module was written: a pool
|
|
41
|
+
# create defaults to them, and a borrow tries them first so the common case needs a
|
|
42
|
+
# single hash.
|
|
43
|
+
CONVERT_LIQUIDATIONS = True
|
|
44
|
+
LIQUIDATION_FEE_PER_MILLE = 40
|
|
41
45
|
|
|
42
46
|
|
|
43
|
-
def _settings() -> Iterator[tuple[
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
def _settings() -> Iterator[tuple[bool, int]]:
|
|
48
|
+
usual = (CONVERT_LIQUIDATIONS, LIQUIDATION_FEE_PER_MILLE)
|
|
49
|
+
yield usual
|
|
50
|
+
for convert in (True, False):
|
|
51
|
+
for fee in range(MAX_FEE_PER_MILLE + 1):
|
|
52
|
+
if (convert, fee) != usual:
|
|
48
53
|
yield convert, fee
|
|
49
54
|
|
|
50
55
|
|
|
@@ -73,21 +78,49 @@ def lender_bond_datum(
|
|
|
73
78
|
"pool sends lender bonds to an address other than the lender manager; "
|
|
74
79
|
"the borrow builder does not support such pools",
|
|
75
80
|
)
|
|
76
|
-
_, (_payment, staking) = constr(pool_datum.lender_bond_address)
|
|
77
|
-
stake_credential = RawPlutusData(
|
|
78
|
-
staking
|
|
79
|
-
if isinstance(staking, cbor2.CBORTag)
|
|
80
|
-
else cbor2.loads(staking.to_cbor()),
|
|
81
|
-
)
|
|
82
81
|
for convert, fee in _settings():
|
|
83
|
-
candidate =
|
|
84
|
-
|
|
85
|
-
lender_stake_credential=stake_credential,
|
|
86
|
-
should_liquidation_convert_to_principal=convert,
|
|
87
|
-
liquidation_fee_per_mille=fee,
|
|
82
|
+
candidate = lender_manager_datum(
|
|
83
|
+
pool_datum,
|
|
88
84
|
pool_id=pool_id,
|
|
89
|
-
|
|
85
|
+
pool_manager=pool_manager,
|
|
86
|
+
convert_liquidations=convert,
|
|
87
|
+
liquidation_fee_per_mille=fee,
|
|
90
88
|
).to_cbor_hex()
|
|
91
89
|
if lender_bond_datum_matches(pool_datum, candidate):
|
|
92
90
|
return candidate
|
|
93
91
|
raise ValueError("no lender-manager setting reproduces the pool's commitment")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def lender_manager_datum(
|
|
95
|
+
pool_datum: PoolDatum,
|
|
96
|
+
*,
|
|
97
|
+
pool_id: bytes,
|
|
98
|
+
pool_manager: PoolManagerDatum,
|
|
99
|
+
convert_liquidations: bool,
|
|
100
|
+
liquidation_fee_per_mille: int,
|
|
101
|
+
) -> LenderManagerDatum:
|
|
102
|
+
"""The lender-manager datum of pool ``pool_id``'s lender bonds.
|
|
103
|
+
|
|
104
|
+
The stake credential is the one of the pool's lender-bond address; the principal
|
|
105
|
+
asset is the pool's.
|
|
106
|
+
"""
|
|
107
|
+
_, (_payment, staking) = constr(pool_datum.lender_bond_address)
|
|
108
|
+
return LenderManagerDatum(
|
|
109
|
+
lender_auth=pool_manager.pool_owner_auth,
|
|
110
|
+
lender_stake_credential=RawPlutusData(
|
|
111
|
+
staking
|
|
112
|
+
if isinstance(staking, cbor2.CBORTag)
|
|
113
|
+
else cbor2.loads(staking.to_cbor()),
|
|
114
|
+
),
|
|
115
|
+
should_liquidation_convert_to_principal=_TRUE
|
|
116
|
+
if convert_liquidations
|
|
117
|
+
else _FALSE,
|
|
118
|
+
liquidation_fee_per_mille=liquidation_fee_per_mille,
|
|
119
|
+
pool_id=pool_id,
|
|
120
|
+
principal_asset=pool_datum.common_data.principal_asset,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def lender_bond_commitment(datum: LenderManagerDatum) -> bytes:
|
|
125
|
+
"""What a pool commits to: ``blake2b_256`` of the lender-bond datum."""
|
|
126
|
+
return hashlib.blake2b(datum.to_cbor(), digest_size=32).digest()
|
|
@@ -49,6 +49,7 @@ from charli3_dendrite.lending.fluidtokens_v4.transactions.common import (
|
|
|
49
49
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import min_ada
|
|
50
50
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import out_ref_of
|
|
51
51
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import script_hash_of
|
|
52
|
+
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import sole_nft_name
|
|
52
53
|
from charli3_dendrite.lending.fluidtokens_v4.transactions.common import (
|
|
53
54
|
withdraw_redeemer_position,
|
|
54
55
|
)
|
|
@@ -78,10 +79,7 @@ _BOOL_TRUE = 1
|
|
|
78
79
|
|
|
79
80
|
def loan_nft_name(loan: Utxo) -> bytes:
|
|
80
81
|
"""The name of the one loan NFT a loan UTxO holds."""
|
|
81
|
-
|
|
82
|
-
if len(names) != 1:
|
|
83
|
-
raise ValueError("loan UTxO must hold exactly one loan NFT")
|
|
84
|
-
return bytes.fromhex(names[0])
|
|
82
|
+
return sole_nft_name(loan, c.LOAN_POLICY, "loan")
|
|
85
83
|
|
|
86
84
|
|
|
87
85
|
@dataclass
|