diff --git a/CHANGELOG.md b/CHANGELOG.md
index 735ea509d1b456b56dec44bbd3039aa7eb2162fc..c2d9876df853248565f1ee21d483881c950572a3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,8 @@ With this release, we dropped support for Coq 8.9.
   have been removed, in particular: `auth_equivI`, `auth_validI`,
   `auth_included`, `auth_valid_discrete`, and `auth_both_op`.  For validity, use
   `auth_auth_valid*`, `auth_frag_valid*`, or `auth_both_valid*` instead.
+* Add the camera of discardable fractions `dfrac`. This is a generalization of
+  the normal fractional camera. See `theories/algebra/dfrac.v` for further information.
 
 **Changes in `proofmode`:**
 
diff --git a/_CoqProject b/_CoqProject
index 7b786138c6cb54915569fef888b47732b85d1922..3d82b5d8b0e8d32c0d415ecdffe94559edc4f1be 100644
--- a/_CoqProject
+++ b/_CoqProject
@@ -23,6 +23,7 @@ theories/algebra/agree.v
 theories/algebra/excl.v
 theories/algebra/functions.v
 theories/algebra/frac.v
+theories/algebra/dfrac.v
 theories/algebra/csum.v
 theories/algebra/list.v
 theories/algebra/vector.v
diff --git a/theories/algebra/dfrac.v b/theories/algebra/dfrac.v
new file mode 100644
index 0000000000000000000000000000000000000000..0a17ebb72578a767bf8e0329bc7dd9dcc8e26507
--- /dev/null
+++ b/theories/algebra/dfrac.v
@@ -0,0 +1,197 @@
+(** Camera of discardable fractions.
+
+    This is a generalisation of the fractional camera where elements can
+    represent both ownership of a fraction (as in the fractional camera) and the
+    knowledge that a fraction has been discarded.
+
+    Ownership of a fraction is denoted [DfracOwn q] and behaves identically to
+    [q] of the fractional camera.
+
+    Knowledge that a fraction has been discarded is denoted [DfracDiscarded p].
+    Elements of this form are their own core, making ownership of them
+    persistent. Resource composition combines knowledge that [p] and [p'] have been
+    discarded into the knowledge that [p max p'] has been discarded.
+
+    One can make a frame preserving update from _owning_ a fraction to _knowing_
+    that the fraction has been discarded.
+
+    Crucially, ownership over 1 is an exclusive element just as it is in the
+    fractional camera. Hence owning 1 implies that no fraction has been
+    discarded. Conversely, knowing that a fraction has been discarded implies
+    that no one can own 1. And, since discarding is an irreversible operation, it
+    also implies that no one can own 1 in the future *)
+
+From Coq.QArith Require Import Qcanon.
+From iris.algebra Require Export cmra proofmode_classes updates.
+From iris Require Import options.
+Set Default Proof Using "Type".
+
+(** An element of dfrac denotes ownership of a fraction, knowledge that a
+    fraction has been discarded, or both. Note that all elements can be written
+    on the form [DfracOwn q â‹… DfracDiscarded p]. This should be used instead
+    of [DfracBoth] which is for internal use only. *)
+Inductive dfrac :=
+  | DfracOwn : Qp → dfrac
+  | DfracDiscarded : Qp → dfrac
+  | DfracBoth : Qp → Qp → dfrac.
+
+Global Instance DfracOwn_inj : Inj (=) (=) DfracOwn.
+Proof. by injection 1. Qed.
+
+Global Instance DfracDiscarded_inj : Inj (=) (=) DfracDiscarded.
+Proof. by injection 1. Qed.
+
+Global Instance DfracBoth_inj : Inj2 (=) (=) (=) DfracBoth.
+Proof. by injection 1. Qed.
+
+Section dfrac.
+
+  Canonical Structure dfracO := leibnizO dfrac.
+
+  Implicit Types p q : Qp.
+
+  Implicit Types x y : dfrac.
+
+  (** An element is valid as long as the sum of its content is less than one. *)
+  Instance dfrac_valid : Valid dfrac := λ x,
+    match x with
+    | DfracOwn q => q ≤ 1%Qp
+    | DfracDiscarded p => p ≤ 1%Qp
+    | DfracBoth q p => (q + p)%Qp ≤ 1%Qp
+    end%Qc.
+
+  (** As in the fractional camera the core is undefined for elements denoting
+     ownership of a fraction. For elements denoting the knowledge that a fraction has
+     been discarded the core is the identity function. *)
+  Instance dfrac_pcore : PCore dfrac := λ x,
+    match x with
+    | DfracOwn q => None
+    | DfracDiscarded p => Some (DfracDiscarded p)
+    | DfracBoth q p => Some (DfracDiscarded p)
+    end.
+
+  (** When elements are combined, ownership is added together and knowledge of
+     discarded fractions is combined with the max operation. *)
+  Instance dfrac_op : Op dfrac := λ x y,
+    match x, y with
+    | DfracOwn q, DfracOwn q' => DfracOwn (q + q')
+    | DfracOwn q, DfracDiscarded p' => DfracBoth q p'
+    | DfracOwn q, DfracBoth q' p' => DfracBoth (q + q') p'
+    | DfracDiscarded p, DfracOwn q' => DfracBoth q' p
+    | DfracDiscarded p, DfracDiscarded p' => DfracDiscarded (p `max` p')
+    | DfracDiscarded p, DfracBoth q' p' => DfracBoth q' (p `max` p')
+    | DfracBoth q p, DfracOwn q' => DfracBoth (q + q') p
+    | DfracBoth q p, DfracDiscarded p' => DfracBoth q (p `max` p')
+    | DfracBoth q p, DfracBoth q' p' => DfracBoth (q + q') (p `max` p')
+    end.
+
+  Lemma dfrac_op_own q p : DfracOwn p â‹… DfracOwn q = DfracOwn (p + q).
+  Proof. done. Qed.
+
+  Lemma dfrac_op_discarded q p :
+    DfracDiscarded p â‹… DfracDiscarded q = DfracDiscarded (p `max` q).
+  Proof. done. Qed.
+
+  Lemma dfrac_own_included q p : DfracOwn q ≼ DfracOwn p ↔ (q < p)%Qc.
+  Proof.
+    rewrite Qp_lt_sum. split.
+    - rewrite /included /op /dfrac_op. intros [[o|?|?] [= ->]]. by exists o.
+    - intros [o ->]. exists (DfracOwn o). by rewrite dfrac_op_own.
+  Qed.
+
+  Lemma dfrac_discarded_included q p :
+    DfracDiscarded q ≼ DfracDiscarded p ↔ (q ≤ p)%Qc.
+  Proof. 
+    split.
+    - rewrite /included /op /dfrac_op. intros [[?|?|?] [= ->]]. apply Qp_le_max_l.
+    - intros ?. exists (DfracDiscarded p).
+      by rewrite dfrac_op_discarded /Qp_max decide_True.
+  Qed.
+
+  Definition dfrac_ra_mixin : RAMixin dfrac.
+  Proof.
+    split; try apply _.
+    - intros [?|?|??] y cx <-; intros [= <-]; eexists _; done.
+    - intros [?|?|??] [?|?|??] [?|?|??];
+        rewrite /op /dfrac_op 1?assoc 1?assoc; done.
+    - intros [?|?|??] [?|?|??];
+        rewrite /op /dfrac_op 1?(comm Qp_plus) 1?(comm Qp_max); done.
+    - intros [?|?|??] cx; rewrite /pcore /dfrac_pcore; intros [= <-];
+        rewrite /op /dfrac_op Qp_max_id; done.
+    - intros [?|?|??] ? [= <-]; done.
+    - intros [?|?|??] [?|?|??] ? [[?|?|??] [=]] [= <-]; eexists _; split; try done;
+        apply dfrac_discarded_included; subst; auto; apply Qp_le_max_l.
+    - intros [q|p|q p] [q'|p'|q' p']; rewrite /op /dfrac_op /valid /dfrac_valid.
+      * apply (Qp_plus_weak_r _ _ 1).
+      * apply (Qp_plus_weak_r _ _ 1).
+      * apply Qcle_trans. etrans; last apply Qp_le_plus_l. apply Qp_le_plus_l.
+      * apply (Qp_plus_weak_l _ _ 1).
+      * apply (Qp_max_lub_l _ _ 1).
+      * by intros ?%(Qp_plus_weak_l _ _ 1)%(Qp_max_lub_l _ _ 1).
+      * rewrite (comm _ _ q') -assoc. apply (Qp_plus_weak_l _ _ 1).
+      * intros H. etrans; last apply H.
+        apply Qcplus_le_mono_l. apply Qp_le_max_l.
+      * intros H. etrans; last apply H.
+        rewrite -assoc. apply Qcplus_le_mono_l, Qp_plus_weak_2_r, Qp_le_max_l.
+  Qed.
+  Canonical Structure dfracR := discreteR dfrac dfrac_ra_mixin.
+
+  Global Instance dfrac_cmra_discrete : CmraDiscrete dfracR.
+  Proof. apply discrete_cmra_discrete. Qed.
+
+  Global Instance dfrac_full_exclusive : Exclusive (DfracOwn 1).
+  Proof.
+    intros [q|p|q p];
+      rewrite /op /cmra_op -cmra_discrete_valid_iff /valid /cmra_valid /=.
+    - apply (Qp_not_plus_ge 1 q).
+    - apply (Qp_not_plus_ge 1 p).
+    - rewrite -Qcplus_assoc. apply (Qp_not_plus_ge 1 (q + p)).
+  Qed.
+
+  Global Instance dfrac_cancelable q : Cancelable (DfracOwn q).
+  Proof.
+    apply: discrete_cancelable.
+    intros [q1|p1|q1 p1][q2|p2|q2 p2] _; rewrite /op /cmra_op; simpl;
+      try by intros [= ->].
+    - by intros ->%(inj _)%(inj _).
+    - by intros [?%symmetry%Qp_plus_id_free _]%(inj2 _).
+    - by intros [?%Qp_plus_id_free ?]%(inj2 _).
+    - by intros [->%(inj _) ->]%(inj2 _).
+  Qed.
+
+  Global Instance frac_id_free q : IdFree (DfracOwn q).
+  Proof.
+    intros [q'|p'|q' p'] _; rewrite /op /cmra_op; simpl; try by intros [=].
+    by intros [= ?%Qp_plus_id_free].
+  Qed.
+
+  Global Instance dfrac_discarded_core_id p : CoreId (DfracDiscarded p).
+  Proof. by constructor. Qed.
+
+  Lemma dfrac_valid_own p : ✓ DfracOwn p ↔ (p ≤ 1%Qp)%Qc.
+  Proof. done. Qed.
+
+  Lemma dfrac_valid_discarded p : ✓ DfracDiscarded p ↔ (p ≤ 1%Qp)%Qc.
+  Proof. done. Qed.
+
+  Lemma dfrac_valid_own_discarded q p :
+    ✓ (DfracOwn q ⋅ DfracDiscarded p) ↔ (q + p ≤ 1%Qp)%Qc.
+  Proof. done. Qed.
+
+  Global Instance is_op_frac q : IsOp' (DfracOwn q) (DfracOwn (q/2)) (DfracOwn (q/2)).
+  Proof. by rewrite /IsOp' /IsOp dfrac_op_own Qp_div_2. Qed.
+
+  (** Discarding a fraction is a frame preserving update. *)
+  Lemma dfrac_discard_update q : DfracOwn q ~~> DfracDiscarded q.
+  Proof.
+    intros n [[q'|p'|q' p']|];
+      rewrite /op /cmra_op -!cmra_discrete_valid_iff /valid /cmra_valid /=.
+    - by rewrite Qcplus_comm.
+    - intro. etrans. apply Qp_max_plus. done.
+    - intro. etrans; last done.
+      rewrite -Qcplus_assoc. rewrite (Qcplus_comm q _). rewrite -Qcplus_assoc.
+      apply Qcplus_le_mono_l. rewrite Qcplus_comm. apply Qp_max_plus.
+    - done.
+  Qed.
+
+End dfrac.
\ No newline at end of file
diff --git a/theories/algebra/frac.v b/theories/algebra/frac.v
index 121c54296ffb66dbda311719239df92be000eba3..85543266dc7049a7933bbfac359545b831fe3dfc 100644
--- a/theories/algebra/frac.v
+++ b/theories/algebra/frac.v
@@ -47,10 +47,7 @@ Global Instance frac_cancelable (q : frac) : Cancelable q.
 Proof. intros ?????. by apply Qp_eq, (inj (Qcplus q)), (Qp_eq (q+y) (q+z))%Qp. Qed.
 
 Global Instance frac_id_free (q : frac) : IdFree q.
-Proof.
-  intros [q0 Hq0] ? EQ%Qp_eq. rewrite -{1}(Qcplus_0_r q) in EQ.
-  eapply Qclt_not_eq; first done. by apply (inj (Qcplus q)).
-Qed.
+Proof. intros p _. apply Qp_plus_id_free. Qed.
 
 Lemma frac_op' (q p : Qp) : (p â‹… q) = (p + q)%Qp.
 Proof. done. Qed.