<p><code>thresh(3,pk(key_1),s:pk(key_2),s:pk(key_3),sdv:older(12960))</code> is no longer a valid Miniscript and won't successfully pass through the Miniscript analyzer on sipa's <a href="https://bitcoin.sipa.be/miniscript/" rel="nofollow noreferrer">site</a>.</p>
<p>The reason for this is there was a MINIMALIF <a href="https://github.com/rust-bitcoin/rust-miniscript/blob/master/doc/security_report_2022_04_20.md" rel="nofollow noreferrer">bug</a> where:</p>
<blockquote>
<p>The wrapper <code>d</code> (OP_DUP OP_IF [X] OP_ENDIF) was incorrectly marked to have the <code>u</code> property. The <code>u</code> property states &quot;When [X] is satisfied, this expression will put an exact 1 on the stack (as opposed to any nonzero value)&quot;. However, this is only true if we have a MINIMALIF consensus rule.</p>
</blockquote>
<p>If you don't respect the MINIMALIF rule (only introduced with Taproot) <code>&lt;3&gt; &lt;&gt; &lt;&gt; &lt;&gt;</code> satisfies the old script without any signatures if the timelock is satisfied.</p>
<p><code>thresh</code> requires the <code>u</code> type modifier which <code>d:</code> doesn't have since the bug fix so <code>d:</code> can no longer be used within a <code>thresh</code>.</p>
<p>Thanks to darosior for answering this on IRC.</p>

CC BY-SA 4.0
2022-09-19T15:54:51.223Z
2022-09-19T15:54:51.223Z
Michael Folkson
<p>The &quot;A 3-of-3 that turns into a 2-of-3 after 90 days&quot; policy:</p>
<p><code>thresh(3,pk(key_1),pk(key_2),pk(key_3),older(12960))</code></p>
<p>compiled to this Miniscript a few months ago:</p>
<p><code>thresh(3,pk(key_1),s:pk(key_2),s:pk(key_3),sdv:older(12960))</code></p>
<p>which can be decoded to this script:</p>
<pre><code>&lt;key_1&gt; OP_CHECKSIG OP_SWAP &lt;key_2&gt; OP_CHECKSIG OP_ADD OP_SWAP &lt;key_3&gt;
OP_CHECKSIG OP_ADD OP_SWAP OP_DUP OP_IF
  &lt;a032&gt; OP_CHECKSEQUENCEVERIFY OP_VERIFY
OP_ENDIF
OP_ADD 3 OP_EQUAL
</code></pre>
<p>Today it compiles to this Miniscript instead (note the <code>sln</code> wrapper instead of the <code>sdv</code> wrapper:</p>
<p><code>thresh(3,pk(key_1),s:pk(key_2),s:pk(key_3),sln:older(12960))</code></p>
<p>which can be decoded to this script:</p>
<pre><code>&lt;key_1&gt; OP_CHECKSIG OP_SWAP &lt;key_2&gt; OP_CHECKSIG OP_ADD OP_SWAP &lt;key_3&gt;
OP_CHECKSIG OP_ADD OP_SWAP OP_IF
  0
OP_ELSE
  &lt;a032&gt; OP_CHECKSEQUENCEVERIFY OP_0NOTEQUAL
OP_ENDIF
OP_ADD 3 OP_EQUAL
</code></pre>
<p>Why has it changed?</p>

CC BY-SA 4.0
2022-09-19T16:36:47.350Z
Just a note, there is no "*the* miniscript for a policy". The compiler has a lot of freedom in determining what miniscript to compile a policy too, and in theory an improved compiler could do better than current version.
Pieter Wuille
<script><miniscript>
Why has the Miniscript for this particular Policy changed over the past few months?
Michael Folkson
# Why has the Miniscript for this particular Policy changed over the past few months?

(Asked by: username_0 on 2022-09-19)

The "A 3-of-3 that turns into a 2-of-3 after 90 days" policy:

`thresh(3,pk(key_1),pk(key_2),pk(key_3),older(12960))`

compiled to this Miniscript a few months ago:

`thresh(3,pk(key_1),s:pk(key_2),s:pk(key_3),sdv:older(12960))`

which can be decoded to this script:

```
<key_1> OP_CHECKSIG OP_SWAP <key_2> OP_CHECKSIG OP_ADD OP_SWAP <key_3>
OP_CHECKSIG OP_ADD OP_SWAP OP_DUP OP_IF
  <a032> OP_CHECKSEQUENCEVERIFY OP_VERIFY
OP_ENDIF
OP_ADD 3 OP_EQUAL

```

Today it compiles to this Miniscript instead (note the `sln` wrapper instead of the `sdv` wrapper:

`thresh(3,pk(key_1),s:pk(key_2),s:pk(key_3),sln:older(12960))`

which can be decoded to this script:

```
<key_1> OP_CHECKSIG OP_SWAP <key_2> OP_CHECKSIG OP_ADD OP_SWAP <key_3>
OP_CHECKSIG OP_ADD OP_SWAP OP_IF
  0
OP_ELSE
  <a032> OP_CHECKSEQUENCEVERIFY OP_0NOTEQUAL
OP_ENDIF
OP_ADD 3 OP_EQUAL

```

Why has it changed?

**Tags:** script, miniscript

> **Comments:**
> **username_1**: Just a note, there is no "*the* miniscript for a policy". The compiler has a lot of freedom in determining what miniscript to compile a policy too, and in theory an improved compiler could do better than current version.  

---

## 1 answers

### Answer by username_0 on 2022-09-19. Score: 2 | Accepted answer

`thresh(3,pk(key_1),s:pk(key_2),s:pk(key_3),sdv:older(12960))` is no longer a valid Miniscript and won't successfully pass through the Miniscript analyzer on sipa's [site](https://bitcoin.sipa.be/miniscript/).

The reason for this is there was a MINIMALIF [bug](https://github.com/rust-bitcoin/rust-miniscript/blob/master/doc/security_report_2022_04_20.md) where:

> The wrapper `d` (OP\_DUP OP\_IF [X] OP\_ENDIF) was incorrectly marked to have the `u` property. The `u` property states "When [X] is satisfied, this expression will put an exact 1 on the stack (as opposed to any nonzero value)". However, this is only true if we have a MINIMALIF consensus rule.

If you don't respect the MINIMALIF rule (only introduced with Taproot) `<3> <> <> <>` satisfies the old script without any signatures if the timelock is satisfied.

`thresh` requires the `u` type modifier which `d:` doesn't have since the bug fix so `d:` can no longer be used within a `thresh`.

Thanks to darosior for answering this on IRC.


---

