Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

### WIP

- Apply per-transaction direct deposits to `CertState` after each `CERTS` step in `SUBLEDGER-V` and `LEDGER-V` (CIP-159).
- Forbid CIP-159 fields (`txDirectDeposits`, `txBalanceIntervals`) in legacy mode via explicit `UTXOW-legacy` premises.
- Allow partial withdrawals in `PRE-CERT` rule; define `applyWithdrawals` and `_≤ᵐ_` (CIP-159).
- Allow partial withdrawals in `PRE-CERT` rule; define `applyWithdrawals` (CIP-159).
- Extend `TxInfo` with `txDirectDeposits` and `txBalanceIntervals` fields (CIP-159).
- Remove `allBalanceIntervals` batch-level aggregation helper; balance interval
assertions will be checked per-(sub)transaction in `UTXO`/`SUBUTXO` rules (see #1117).
Expand Down
2 changes: 0 additions & 2 deletions src/Ledger/Conway/Conformance/Properties.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ module _ (s : ChainState) where
-- Transaction properties

module _ {slot} {tx} (let txb = body tx) (valid : validTxIn₂ s slot tx)
(indexedSum-∪⁺-hom : ∀ {A V : Type} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq V ⦄ ⦃ mon : CommutativeMonoid 0ℓ 0ℓ V ⦄
→ (d₁ d₂ : A ⇀ V) → indexedSumᵛ' id (d₁ ∪⁺ d₂) ≡ indexedSumᵛ' id d₁ ◇ indexedSumᵛ' id d₂)
(indexedSum-⊆ : ∀ {A : Type} ⦃ _ : DecEq A ⦄ (d d' : A ⇀ ℕ) → d ˢ ⊆ d' ˢ
→ indexedSumᵛ' id d ≤ indexedSumᵛ' id d') -- technically we could use an ordered monoid instead of ℕ
where
Expand Down
17 changes: 5 additions & 12 deletions src/Ledger/Conway/Specification/Certs/Properties/PoV.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,12 @@ private variable
instance
_ = +-0-monoid

module Certs-PoV ( indexedSumᵛ'-∪' : {A : Type} ⦃ _ : DecEq A ⦄ (m m' : A ⇀ Coin)
→ disjoint (dom m) (dom m')
→ getCoin (m ∪ˡ m') ≡ getCoin m + getCoin m' )
-- TODO: prove some or all of the following assumptions, used in roof of `CERTBASE-pov`.
( sumConstZero' : {A : Type} ⦃ _ : DecEq A ⦄ {X : ℙ A} → getCoin (constMap X 0) ≡ 0 )
( res-decomp' : {A : Type} ⦃ _ : DecEq A ⦄ (m m' : A ⇀ Coin)
→ (m ∪ˡ m')ˢ ≡ᵉ (m ∪ˡ (m' ∣ dom (m ˢ) ᶜ))ˢ )
( getCoin-cong' : {A : Type} ⦃ _ : DecEq A ⦄ (s : A ⇀ Coin) (s' : ℙ (A × Coin)) → s ˢ ≡ᵉ s'
→ indexedSum' proj₂ (s ˢ) ≡ indexedSum' proj₂ s' )
( ≡ᵉ-getCoinˢ' : {A A' : Type} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq A' ⦄ (s : ℙ (A × Coin)) {f : A → A'}
→ InjectiveOn (dom s) f → getCoin (mapˢ (map₁ f) s) ≡ getCoin s )
module Certs-PoV
-- TODO: prove the following assumption, used in roof of `CERTBASE-pov`.
( ≡ᵉ-getCoinˢ' : {A A' : Type} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq A' ⦄ (s : ℙ (A × Coin)) {f : A → A'}
→ InjectiveOn (dom s) f → getCoin (mapˢ (map₁ f) s) ≡ getCoin s )
where
open Certs-Pov-lemmas indexedSumᵛ'-∪' sumConstZero' res-decomp' getCoin-cong' ≡ᵉ-getCoinˢ'
open Certs-Pov-lemmas ≡ᵉ-getCoinˢ'
```
-->

Expand Down
126 changes: 46 additions & 80 deletions src/Ledger/Conway/Specification/Certs/Properties/PoVLemmas.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ open import Axiom.Set.Properties th
open import Algebra using (CommutativeMonoid)
open import Data.Maybe.Properties
open import Data.Nat.Properties using (+-0-monoid; +-0-commutativeMonoid; +-identityʳ; +-identityˡ)
open import Relation.Binary using (IsEquivalence)
import Relation.Binary as Eq using (IsEquivalence)
open import Relation.Nullary.Decidable
open import Tactic.ReduceDec

Expand All @@ -40,35 +40,7 @@ private variable
instance
_ = +-0-monoid

getCoin-singleton : ⦃ _ : DecEq A ⦄ {(a , c) : A × Coin} → indexedSumᵛ' id ❴ (a , c) ❵ ≡ c
getCoin-singleton = indexedSum-singleton' {M = Coin} (finiteness _)

∪ˡsingleton∈dom : ⦃ _ : DecEq A ⦄ (m : A ⇀ Coin) {(a , c) : A × Coin}
→ a ∈ dom m → getCoin (m ∪ˡ ❴ (a , c) ❵ᵐ) ≡ getCoin m
∪ˡsingleton∈dom m {(a , c)} a∈dom = ≡ᵉ-getCoin (m ∪ˡ ❴ (a , c) ❵) m (singleton-∈-∪ˡ {m = m} a∈dom)

module _ ( indexedSumᵛ'-∪ : {A : Type} ⦃ _ : DecEq A ⦄ (m m' : A ⇀ Coin)
→ disjoint (dom m) (dom m')
→ getCoin (m ∪ˡ m') ≡ getCoin m + getCoin m' )
where
open ≡-Reasoning
open Equivalence

∪ˡsingleton∉dom : ⦃ _ : DecEq A ⦄ (m : A ⇀ Coin) {(a , c) : A × Coin}
→ a ∉ dom m → getCoin (m ∪ˡ ❴ (a , c) ❵ᵐ) ≡ getCoin m + c
∪ˡsingleton∉dom m {(a , c)} a∉dom = begin
getCoin (m ∪ˡ ❴ a , c ❵ᵐ)
≡⟨ indexedSumᵛ'-∪ m ❴ a , c ❵ᵐ
( λ x y → a∉dom (subst (_∈ dom m) (from ∈-dom-singleton-pair y) x) ) ⟩
getCoin m + getCoin ❴ a , c ❵ᵐ
≡⟨ cong (getCoin m +_) getCoin-singleton ⟩
getCoin m + c

∪ˡsingleton0≡ : ⦃ _ : DecEq A ⦄ → (m : A ⇀ Coin) {a : A} → getCoin (m ∪ˡ ❴ (a , 0) ❵ᵐ) ≡ getCoin m
∪ˡsingleton0≡ m {a} with a ∈? dom m
... | yes a∈dom = ∪ˡsingleton∈dom m a∈dom
... | no a∉dom = trans (∪ˡsingleton∉dom m a∉dom) (+-identityʳ (getCoin m))
open ≡-Reasoning
```
-->

Expand All @@ -83,61 +55,55 @@ some `dcert`{.AgdaBound} : `DCert`{.AgdaDatatype}. Then,
*Formally*.

```agda
CERT-pov : {Γ : CertEnv} {s s' : CertState}
→ Γ ⊢ s ⇀⦇ dCert ,CERT⦈ s'
→ getCoin s ≡ getCoin s'
CERT-pov : {Γ : CertEnv} {s s' : CertState}
→ Γ ⊢ s ⇀⦇ dCert ,CERT⦈ s' → getCoin s ≡ getCoin s'
```

*Proof*. (Click the "Show more Agda" button to reveal the proof.)

<!--
```agda
CERT-pov (CERT-deleg (DELEG-delegate {rwds = rwds} _)) = sym (∪ˡsingleton0≡ rwds)
CERT-pov (CERT-deleg (DELEG-reg {rwds = rwds} _)) = sym (∪ˡsingleton0≡ rwds)
CERT-pov {s = ⟦ _ , stᵖ , stᵍ ⟧ᶜˢ}{⟦ _ , stᵖ' , stᵍ' ⟧ᶜˢ}
(CERT-deleg (DELEG-dereg {c = c} {rwds} {vDelegs = vDelegs}{sDelegs} x)) = begin
getCoin ⟦ ⟦ vDelegs , sDelegs , rwds ⟧ , stᵖ , stᵍ ⟧
≡˘⟨ ≡ᵉ-getCoin rwds-∪ˡ-decomp rwds
( ≡ᵉ.trans rwds-∪ˡ-∪ (≡ᵉ.trans ∪-sym (res-ex-∪ Dec-∈-singleton)) ) ⟩
getCoin rwds-∪ˡ-decomp
≡⟨ ≡ᵉ-getCoin rwds-∪ˡ-decomp ((rwds ∣ ❴ c ❵ ᶜ) ∪ˡ ❴ (c , 0) ❵ᵐ) rwds-∪ˡ≡sing-∪ˡ ⟩
getCoin ((rwds ∣ ❴ c ❵ ᶜ) ∪ˡ ❴ (c , 0) ❵ᵐ )
≡⟨ ∪ˡsingleton0≡ (rwds ∣ ❴ c ❵ ᶜ) ⟩
getCoin ⟦ ⟦ vDelegs ∣ ❴ c ❵ ᶜ , sDelegs ∣ ❴ c ❵ ᶜ , rwds ∣ ❴ c ❵ ᶜ ⟧ , stᵖ' , stᵍ' ⟧
where
module ≡ᵉ = IsEquivalence (≡ᵉ-isEquivalence {Credential × Coin})
rwds-∪ˡ-decomp = (rwds ∣ ❴ c ❵ ᶜ) ∪ˡ (rwds ∣ ❴ c ❵ )

rwds-∪ˡ-∪ : rwds-∪ˡ-decomp ˢ ≡ᵉ (rwds ∣ ❴ c ❵ ᶜ)ˢ ∪ (rwds ∣ ❴ c ❵)ˢ
rwds-∪ˡ-∪ = disjoint-∪ˡ-∪ (disjoint-sym res-ex-disjoint)

disj : disjoint (dom ((rwds ∣ ❴ c ❵ˢ ᶜ) ˢ)) (dom (❴ c , 0 ❵ᵐ ˢ))
disj {a} a∈res a∈dom = res-comp-dom a∈res (dom-single→single a∈dom)

rwds-∪ˡ≡sing-∪ˡ : rwds-∪ˡ-decomp ˢ ≡ᵉ ((rwds ∣ ❴ c ❵ ᶜ) ∪ˡ ❴ (c , 0) ❵ᵐ )ˢ
rwds-∪ˡ≡sing-∪ˡ = ≡ᵉ.trans rwds-∪ˡ-∪
( ≡ᵉ.trans (∪-cong ≡ᵉ.refl (res-singleton'{m = rwds} x))
(≡ᵉ.sym $ disjoint-∪ˡ-∪ disj) )
CERT-pov (CERT-pool x) = refl
CERT-pov (CERT-vdel x) = refl

injOn : (wdls : Withdrawals)
→ ∀[ a ∈ dom (wdls ˢ) ] NetworkIdOf a ≡ NetworkId
→ InjectiveOn (dom (wdls ˢ)) RewardAddress.stake
injOn _ h {record { stake = stakex }} {record { stake = stakey }} x∈ y∈ refl =
cong (λ u → record { net = u ; stake = stakex }) (trans (h x∈) (sym (h y∈)))

module Certs-Pov-lemmas
-- TODO: prove some or all of the following assumptions, used in roof of `CERTBASE-pov`.
( sumConstZero : {A : Type} ⦃ _ : DecEq A ⦄ {X : ℙ A} → getCoin (constMap X 0) ≡ 0 )
( res-decomp : {A : Type} ⦃ _ : DecEq A ⦄ (m m' : A ⇀ Coin)
→ (m ∪ˡ m')ˢ ≡ᵉ (m ∪ˡ (m' ∣ dom (m ˢ) ᶜ))ˢ )
( getCoin-cong : {A : Type} ⦃ _ : DecEq A ⦄ (s : A ⇀ Coin) (s' : ℙ (A × Coin)) → s ˢ ≡ᵉ s'
→ indexedSum' proj₂ (s ˢ) ≡ indexedSum' proj₂ s' )
( ≡ᵉ-getCoinˢ : {A A' : Type} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq A' ⦄ (s : ℙ (A × Coin)) {f : A → A'}
→ InjectiveOn (dom s) f → getCoin (mapˢ (map₁ f) s) ≡ getCoin s )
where
CERT-pov (CERT-deleg (DELEG-delegate {rwds = rwds} _)) = sym (∪ˡsingleton0≡ rwds)
CERT-pov (CERT-deleg (DELEG-reg {rwds = rwds} _)) = sym (∪ˡsingleton0≡ rwds)
CERT-pov {s = ⟦ _ , stᵖ , stᵍ ⟧ᶜˢ}{⟦ _ , stᵖ' , stᵍ' ⟧ᶜˢ}
(CERT-deleg (DELEG-dereg {c = c} {rwds} {vDelegs = vDelegs}{sDelegs} x)) = begin
getCoin ⟦ ⟦ vDelegs , sDelegs , rwds ⟧ , stᵖ , stᵍ ⟧
≡˘⟨ ≡ᵉ-getCoin rwds-∪ˡ-decomp rwds
( ≡ᵉ.trans rwds-∪ˡ-∪ (≡ᵉ.trans ∪-sym (res-ex-∪ Dec-∈-singleton)) ) ⟩
getCoin rwds-∪ˡ-decomp
≡⟨ ≡ᵉ-getCoin rwds-∪ˡ-decomp ((rwds ∣ ❴ c ❵ ᶜ) ∪ˡ ❴ (c , 0) ❵ᵐ) rwds-∪ˡ≡sing-∪ˡ ⟩
getCoin ((rwds ∣ ❴ c ❵ ᶜ) ∪ˡ ❴ (c , 0) ❵ᵐ )
≡⟨ ∪ˡsingleton0≡ (rwds ∣ ❴ c ❵ ᶜ) ⟩
getCoin ⟦ ⟦ vDelegs ∣ ❴ c ❵ ᶜ , sDelegs ∣ ❴ c ❵ ᶜ , rwds ∣ ❴ c ❵ ᶜ ⟧ , stᵖ' , stᵍ' ⟧
where
module ≡ᵉ = Eq.IsEquivalence (≡ᵉ-isEquivalence {Credential × Coin})
rwds-∪ˡ-decomp = (rwds ∣ ❴ c ❵ ᶜ) ∪ˡ (rwds ∣ ❴ c ❵ )

rwds-∪ˡ-∪ : rwds-∪ˡ-decomp ˢ ≡ᵉ (rwds ∣ ❴ c ❵ ᶜ)ˢ ∪ (rwds ∣ ❴ c ❵)ˢ
rwds-∪ˡ-∪ = disjoint-∪ˡ-∪ (disjoint-sym res-ex-disjoint)

disj : disjoint (dom ((rwds ∣ ❴ c ❵ˢ ᶜ) ˢ)) (dom (❴ c , 0 ❵ᵐ ˢ))
disj {a} a∈res a∈dom = res-comp-dom a∈res (dom-single→single a∈dom)

rwds-∪ˡ≡sing-∪ˡ : rwds-∪ˡ-decomp ˢ ≡ᵉ ((rwds ∣ ❴ c ❵ ᶜ) ∪ˡ ❴ (c , 0) ❵ᵐ )ˢ
rwds-∪ˡ≡sing-∪ˡ = ≡ᵉ.trans rwds-∪ˡ-∪
( ≡ᵉ.trans (∪-cong ≡ᵉ.refl (res-singleton'{m = rwds} x))
(≡ᵉ.sym $ disjoint-∪ˡ-∪ disj) )
CERT-pov (CERT-pool x) = refl
CERT-pov (CERT-vdel x) = refl

injOn : (wdls : Withdrawals)
→ ∀[ a ∈ dom (wdls ˢ) ] NetworkIdOf a ≡ NetworkId
→ InjectiveOn (dom (wdls ˢ)) RewardAddress.stake
injOn _ h {record { stake = stakex }} {record { stake = stakey }} x∈ y∈ refl =
cong (λ u → record { net = u ; stake = stakex }) (trans (h x∈) (sym (h y∈)))

module Certs-Pov-lemmas
-- TODO: prove the following assumption, used in roof of `CERTBASE-pov`.
( ≡ᵉ-getCoinˢ : {A A' : Type} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq A' ⦄ (s : ℙ (A × Coin)) {f : A → A'}
→ InjectiveOn (dom s) f → getCoin (mapˢ (map₁ f) s) ≡ getCoin s )
where
```
-->

Expand Down Expand Up @@ -175,7 +141,7 @@ value of the withdrawals in `Γ`{.AgdaBound}. In other terms,
let
open DState (dState cs )
open DState (dState cs') renaming (rewards to rewards')
module ≡ᵉ = IsEquivalence (≡ᵉ-isEquivalence {Credential × Coin})
module ≡ᵉ = Eq.IsEquivalence (≡ᵉ-isEquivalence {Credential × Coin})
wdrlsCC = mapˢ (map₁ RewardAddress.stake) (wdrls ˢ)
zeroMap = constMap (mapˢ RewardAddress.stake (dom wdrls)) 0
rwds-∪ˡ-decomp = (rewards ∣ dom wdrlsCC ᶜ) ∪ˡ (rewards ∣ dom wdrlsCC)
Expand Down
16 changes: 5 additions & 11 deletions src/Ledger/Conway/Specification/Ledger/Properties/PoV.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,9 @@ instance

module _
(tx : Tx) (let open Tx tx; open TxBody body)
( indexedSumᵛ'-∪ : {A : Type} ⦃ _ : DecEq A ⦄ (m m' : A ⇀ Coin)
→ disjoint (dom m) (dom m') → getCoin (m ∪ˡ m') ≡ getCoin m + getCoin m' )
( sumConstZero : {A : Type} ⦃ _ : DecEq A ⦄ {X : ℙ A} → getCoin (constMap X 0) ≡ 0 )
( res-decomp : {A : Type} ⦃ _ : DecEq A ⦄ (m m' : A ⇀ Coin)
→ (m ∪ˡ m')ˢ ≡ᵉ (m ∪ˡ (m' ∣ dom (m ˢ) ᶜ))ˢ )
( getCoin-cong : {A : Type} ⦃ _ : DecEq A ⦄ (s : A ⇀ Coin) (s' : ℙ (A × Coin)) → s ˢ ≡ᵉ s'
→ indexedSum' proj₂ (s ˢ) ≡ indexedSum' proj₂ s' )
( ≡ᵉ-getCoinˢ : {A A' : Type} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq A' ⦄ (s : ℙ (A × Coin)) {f : A → A'}
→ InjectiveOn (dom s) f → getCoin (mapˢ (map₁ f) s) ≡ getCoin s )
-- TODO: prove the following assumption, used in roof of `CERTBASE-pov`.
( ≡ᵉ-getCoinˢ : {A A' : Type} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq A' ⦄ (s : ℙ (A × Coin)) {f : A → A'}
→ InjectiveOn (dom s) f → getCoin (mapˢ (map₁ f) s) ≡ getCoin s )
where

pattern UTXO-induction r = UTXO-inductive⋯ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ r _ _ _
Expand Down Expand Up @@ -84,8 +78,8 @@ then the coin values of `s`{.AgdaBound} and `s'`{.AgdaBound} are equal, that is,
open LState s' renaming (utxoSt to utxoSt'; govSt to govSt'; certState to certState')
open CertState certState'
open ≡-Reasoning
open Certs-PoV indexedSumᵛ'-∪ sumConstZero res-decomp getCoin-cong ≡ᵉ-getCoinˢ
zeroMap = constMap (mapˢ RewardAddress.stake (dom txWithdrawals)) 0
open Certs-PoV ≡ᵉ-getCoinˢ
zeroMap = constMap (mapˢ RewardAddress.stake (dom txWithdrawals)) 0
in
begin
getCoin utxoSt + getCoin certState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ coin∅ = begin
0 ∎
where open Prelude.≡-Reasoning

getCoin-singleton : ((dp , c) : DepositPurpose × Coin) → indexedSumᵛ' id ❴ (dp , c) ❵ ≡ c
getCoin-singleton _ = indexedSum-singleton' {A = DepositPurpose × Coin} {f = proj₂} (finiteness _)

module _ -- ASSUMPTION --
(gc-hom : (d₁ d₂ : Deposits) → getCoin (d₁ ∪⁺ d₂) ≡ getCoin d₁ + getCoin d₂)
where
Expand All @@ -63,7 +60,7 @@ module _ -- ASSUMPTION --
getCoin (deps ∪⁺ ❴ (dp , c) ❵)
≡⟨ gc-hom deps ❴ (dp , c) ❵ ⟩
getCoin deps + getCoin{A = Deposits} ❴ (dp , c) ❵
≡⟨ cong (getCoin deps +_) (getCoin-singleton (dp , c))
≡⟨ cong (getCoin deps +_) getCoin-singleton ⟩
getCoin deps + c
where open Prelude.≡-Reasoning
Expand Down
31 changes: 16 additions & 15 deletions src/Ledger/Dijkstra/Specification/Certs.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ record PState : Type where
field
pools : Pools
fPools : Pools
retiring : KeyHash ⇀ Epoch
retiring : Retiring
deposits : KeyHash ⇀ Coin

record GState : Type where
constructor ⟦_,_,_⟧ᵛ
field
dreps : DReps
ccHotKeys : Credential ⇀ Maybe Credential
ccHotKeys : CCHotKeys
deposits : Credential ⇀ Coin

record CertState : Type where
Expand Down Expand Up @@ -294,22 +294,23 @@ The `LEDGER`{.AgdaDatatype} rule will call `applyDirectDeposits`{.AgdaFunction}
credit direct deposits to account balances as part of processing a transaction batch.

```agda
-- For each withdrawal entry `(addr, amt)`, look up `stake addr` in the acc,
-- compute `bal ∸ amt`, create a singleton map with the new balance, and
-- merge it with the rest (complement-restricted, to remove the old entry).
applyOne : Rewards → RewardAddress × Coin → Rewards
applyOne acc (addr , amt) =
case lookupᵐ? acc (stake addr) of λ where
(just bal) → ❴ stake addr , bal ∸ amt ❵ ∪ˡ (acc ∣ ❴ stake addr ❵ ᶜ)
nothing → acc
-- `nothing` case is defensive; the PRE-CERT precondition guarantees the
-- credential is registered, but handling it makes the function total.

applyWithdrawals : Withdrawals → Rewards → Rewards
applyWithdrawals wdrls rwds =
foldl applyOne rwds (setToList (wdrls ˢ))
where
-- For each withdrawal entry `(addr, amt)`, look up `stake addr` in the acc,
-- compute `bal ∸ amt`, create a singleton map with the new balance, and
-- merge it with the rest (complement-restricted, to remove the old entry).
applyOne : Rewards → RewardAddress × Coin → Rewards
applyOne acc (addr , amt) =
case lookupᵐ? acc (stake addr) of λ where
(just bal) → ❴ stake addr , bal ∸ amt ❵ ∪ˡ (acc ∣ ❴ stake addr ❵ ᶜ)
nothing → acc
-- `nothing` case is defensive; the PRE-CERT precondition guarantees the
-- credential is registered, but handling it makes the function total.
applyWithdrawals wdrls rwds = foldl applyOne rwds (setToList (wdrls ˢ))
```



In the Dijkstra era, CIP-159 allows **partial withdrawals**: a transaction may
withdraw any amount up to the current account balance.
`applyWithdrawals`{.AgdaFunction} subtracts each withdrawal amount from the
Expand Down
3 changes: 3 additions & 0 deletions src/Ledger/Dijkstra/Specification/Certs/Properties.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ module Ledger.Dijkstra.Specification.Certs.Properties where
-->

```agda
open import Ledger.Dijkstra.Specification.Certs.Properties.ApplyWithdrawalsPoV
open import Ledger.Dijkstra.Specification.Certs.Properties.Computational
open import Ledger.Dijkstra.Specification.Certs.Properties.PoV
open import Ledger.Dijkstra.Specification.Certs.Properties.PoVLemmas
```
Loading
Loading