55\begin{code}[hide]
66{-# OPTIONS --safe #-}
77
8- open import Data.Nat.Properties using (+-0-monoid; +-0-commutativeMonoid)
98open import Data.Integer using () renaming (+_ to pos)
9+ import Data.Integer as ℤ
10+ open import Data.Integer.Properties using (module ≤-Reasoning; +-mono-≤; neg-mono-≤; +-identityˡ)
11+ renaming (nonNegative⁻¹ to nonNegative⁻¹ℤ)
1012open import Data.Nat.GeneralisedArithmetic using (iterate)
11- open import Data.Rational using (ℚ; floor; _*_; _÷_; _/_)
13+ open import Data.Rational using (ℚ; floor; _*_; _÷_; _/_; _⊓_; _≟_; ≢-nonZero )
1214open import Data.Rational.Literals using (number; fromℤ)
13- import Data.Rational as ℚ renaming (_⊓_ to min)
15+ open import Data.Rational.Properties using (nonNegative⁻¹; pos⇒nonNeg; ⊓-glb)
16+ open import stdlib.Data.Rational.Properties using (0≤⇒0≤floor; ÷-0≤⇒0≤; fromℕ-0≤; *-0≤⇒0≤; fromℤ-0≤)
17+
18+ open import Data.Integer.Tactic.RingSolver using (solve-∀)
1419
1520open import Agda.Builtin.FromNat
1621
17- open import Ledger.Prelude hiding (iterate; _/_; _*_)
22+ open import Ledger.Prelude hiding (iterate; _/_; _*_; _⊓_; _≟_; ≢-nonZero )
1823open Filter using (filter)
1924open import Ledger.Conway.Abstract
2025open import Ledger.Conway.Transaction
@@ -71,6 +76,12 @@ instance
7176
7277 Hastreasury-EpochState : Hastreasury EpochState
7378 Hastreasury-EpochState .treasuryOf = Acnt.treasury ∘ EpochState.acnt
79+
80+ Hasreserves-EpochState : Hasreserves EpochState
81+ Hasreserves-EpochState .reservesOf = Acnt.reserves ∘ EpochState.acnt
82+
83+ HasPParams-EpochState : HasPParams EpochState
84+ HasPParams-EpochState .PParamsOf = PParamsOf ∘ EnactStateOf
7485\end{code}
7586\begin{NoConway}
7687\begin{code}
@@ -117,13 +128,10 @@ instance
117128 HasRewards-NewEpochState : HasRewards NewEpochState
118129 HasRewards-NewEpochState .RewardsOf = RewardsOf ∘ CertStateOf
119130
120- unquoteDecl HasCast-RewardUpdate HasCast-EpochState HasCast-NewEpochState = derive-HasCast
121- ( (quote RewardUpdate , HasCast-RewardUpdate)
122- ∷ (quote EpochState , HasCast-EpochState)
131+ unquoteDecl HasCast-EpochState HasCast-NewEpochState = derive-HasCast
132+ ( (quote EpochState , HasCast-EpochState)
123133 ∷ [ (quote NewEpochState , HasCast-NewEpochState)])
124134
125- instance _ = +-0-monoid; _ = +-0-commutativeMonoid
126-
127135toRwdAddr : Credential → RwdAddr
128136toRwdAddr x = record { net = NetworkId ; stake = x }
129137
@@ -175,35 +183,85 @@ described in \textcite[\sectionname~6.4]{shelley-delegation-design}.
175183\begin{figure*}[h]
176184\begin{AgdaMultiCode}
177185\begin{code}
178-
179186createRUpd : ℕ → BlocksMade → EpochState → Coin → RewardUpdate
180- createRUpd slotsPerEpoch b es total
181- = ⟦ Δt₁ , 0 - Δr₁ + Δr₂ , 0 - feeSS , rs ⟧
187+ createRUpd slotsPerEpoch b es total =
188+ record { Δt = Δt₁
189+ ; Δr = 0 - Δr₁ + Δr₂
190+ ; Δf = 0 - pos feeSS
191+ ; rs = rs
192+ \end{code}
193+ \begin{code}[hide]
194+ ; flowConservation = flowConservation
195+ ; Δt-nonnegative = Δt-nonneg
196+ ; Δf-nonpositive = Δf-nonpos
197+ \end{code}
198+ \begin{code}
199+ }
182200 where
183- prevPp = PParamsOf (es .EpochState.es)
184- reserves = es .EpochState.acnt .Acnt.reserves
185- pstakego = es .EpochState.ss .Snapshots.go
186- feeSS = es .EpochState.ss .Snapshots.feeSS
187- stake = pstakego .Snapshot.stake
188- delegs = pstakego .Snapshot.delegations
189- poolParams = pstakego .Snapshot.poolParameters
190-
191- blocksMade = ∑[ m ← b ] m
192-
193- rho = fromUnitInterval (prevPp .PParams.monetaryExpansion)
194- η = fromℕ blocksMade ÷₀ (fromℕ slotsPerEpoch * ActiveSlotCoeff)
195- Δr₁ = floor (ℚ.min 1 η * rho * fromℕ reserves)
196-
197- rewardPot = pos feeSS + Δr₁
198- tau = fromUnitInterval (prevPp .PParams.treasuryCut)
199- Δt₁ = floor (tau * fromℤ rewardPot)
200- R = posPart (rewardPot - Δt₁)
201- circulation = total - reserves
202-
203- rs = reward prevPp b R poolParams stake delegs circulation
204- Δr₂ = R - ∑[ c ← rs ] c
201+ prevPp = PParamsOf es
202+ reserves = reservesOf es
203+ pstakego = es .EpochState.ss .Snapshots.go
204+ feeSS = es .EpochState.ss .Snapshots.feeSS
205+ stake = pstakego .Snapshot.stake
206+ delegs = pstakego .Snapshot.delegations
207+ poolParams = pstakego .Snapshot.poolParameters
208+ blocksMade = ∑[ m ← b ] m
209+ ρ = fromUnitInterval (prevPp .PParams.monetaryExpansion)
210+ η = fromℕ blocksMade ÷₀ (fromℕ slotsPerEpoch * ActiveSlotCoeff)
211+ Δr₁ = floor (1 ⊓ η * ρ * fromℕ reserves)
212+ rewardPot = pos feeSS + Δr₁
213+ τ = fromUnitInterval (prevPp .PParams.treasuryCut)
214+ Δt₁ = floor (fromℤ rewardPot * τ)
215+ R = rewardPot - Δt₁
216+ circulation = total - reserves
217+ rs = reward prevPp b (posPart R) poolParams stake delegs circulation
218+ Δr₂ = R - pos (∑[ c ← rs ] c)
205219
206220\end{code}
221+ \begin{code}[hide]
222+ -- Proofs
223+ -- Note: Overloading of + and - seems to interfere with
224+ -- the ring solver.
225+ lemmaFlow : ∀ (t₁ r₁ f z : ℤ)
226+ → (t₁ ℤ.+ (0 ℤ.- r₁ ℤ.+ ((f ℤ.+ r₁ ℤ.- t₁) ℤ.- z)) ℤ.+ (0 ℤ.- f) ℤ.+ z) ≡ 0
227+ lemmaFlow = solve-∀
228+ flowConservation = lemmaFlow Δt₁ Δr₁ (pos feeSS) (pos (∑[ c ← rs ] c))
229+
230+ ÷₀-0≤⇒0≤ : ∀ (x y : ℚ) → 0 ≤ x → 0 ≤ y → 0 ≤ (x ÷₀ y)
231+ ÷₀-0≤⇒0≤ x y 0≤x 0≤y with y ≟ 0
232+ ... | (yes y≡0) = nonNegative⁻¹ 0
233+ ... | (no y≢0) = ÷-0≤⇒0≤ x y {{≢-nonZero y≢0}} 0≤x 0≤y
234+
235+ η-nonneg : 0 ≤ η
236+ η-nonneg = ÷₀-0≤⇒0≤ _ _ (fromℕ-0≤ blocksMade)
237+ (*-0≤⇒0≤ _ _
238+ (fromℕ-0≤ slotsPerEpoch)
239+ (nonNegative⁻¹ ActiveSlotCoeff {{pos⇒nonNeg ActiveSlotCoeff}}))
240+
241+ min1η-nonneg : 0 ≤ 1 ⊓ η
242+ min1η-nonneg = ⊓-glb (nonNegative⁻¹ 1) η-nonneg
243+
244+ Δr₁-nonneg : 0 ≤ Δr₁
245+ Δr₁-nonneg = 0≤⇒0≤floor _
246+ (*-0≤⇒0≤ (1 ⊓ η * ρ) (fromℕ reserves)
247+ (UnitInterval-*-0≤ (1 ⊓ η) (prevPp .PParams.monetaryExpansion) min1η-nonneg)
248+ (fromℕ-0≤ reserves))
249+
250+ rewardPot-nonneg : 0 ≤ rewardPot
251+ rewardPot-nonneg = +-mono-≤ (nonNegative⁻¹ℤ (pos feeSS)) Δr₁-nonneg
252+
253+ Δt-nonneg : 0 ≤ Δt₁
254+ Δt-nonneg = 0≤⇒0≤floor _
255+ (UnitInterval-*-0≤ (fromℤ rewardPot) (prevPp .PParams.treasuryCut)
256+ (fromℤ-0≤ rewardPot rewardPot-nonneg))
257+
258+ Δf-nonpos : (0 - pos feeSS) ≤ 0
259+ Δf-nonpos = begin
260+ 0 - pos feeSS ≡⟨ +-identityˡ _ ⟩
261+ ℤ.- pos feeSS ≤⟨ neg-mono-≤ (ℤ.+≤+ z≤n) ⟩
262+ 0 ∎
263+ where open ≤-Reasoning
264+ \end{code}
207265\end{AgdaMultiCode}
208266\caption{RewardUpdate Creation}
209267\label{fig:functions:createRUpd}
@@ -215,7 +273,7 @@ createRUpd slotsPerEpoch b es total
215273{\small
216274\begin{code}
217275applyRUpd : RewardUpdate → EpochState → EpochState
218- applyRUpd ⟦ Δt , Δr , Δf , rs ⟧ʳᵘ
276+ applyRUpd rewardUpdate
219277 ⟦ ⟦ treasury , reserves ⟧ᵃ
220278 , ss
221279 , ⟦ ⟦ utxo , fees , deposits , donations ⟧ᵘ
@@ -233,6 +291,7 @@ applyRUpd ⟦ Δt , Δr , Δf , rs ⟧ʳᵘ
233291 , es
234292 , fut ⟧
235293 where
294+ open RewardUpdate rewardUpdate using (Δt; Δr; Δf; rs)
236295 regRU = rs ∣ dom rewards
237296 unregRU = rs ∣ dom rewards ᶜ
238297 unregRU' = ∑[ x ← unregRU ] x
0 commit comments