Skip to content
Merged
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
30 changes: 29 additions & 1 deletion crates/deadcat-client/tests/simplicity_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use elements::{AssetId, LockTime, OutPoint, Script, Sequence, TxOut, TxOutWitnes
use serde::Serialize;
use simplex::simplicityhl::simplicity::Cost;

// Rounded CI ceilings with headroom above the typed-action maxima of 3,633,302
// Rounded CI ceilings with headroom above the oracle-precomputed maxima of 3,633,302
// mw, 72,462 cells, 62 frames, 4,339 stack bytes, 13,624 transaction bytes,
// 15,574 WU, and 3,894 vB. The exact measurements are emitted by the test.
const MAX_MARKET_COVENANT_COST_MILLIWEIGHT: u64 = 4_000_000;
Expand Down Expand Up @@ -1401,6 +1401,34 @@ fn market_coordinator_rejects_adversarial_solvency_and_authorization_mutations()
"coordinator accepted a valid NO attestation with a YES continuation"
);

let (no_resolution_plan, _, no_resolution) = finalized_market_fixture(
&compiled,
active,
resolve_no,
RtSide::A,
input_base,
output_base,
);
let yes_signature_for_no = direct_market_witness(
&no_resolution_plan,
resolve_no,
resolution_attestation,
coordinator,
output_base,
);
assert!(
compiled
.execute(
coordinator,
&no_resolution,
&yes_signature_for_no.build_witness(),
input_base,
&network,
)
.is_err(),
"coordinator accepted a valid YES signature for the NO message"
);

let mut wrong_resolution_collateral = resolution.clone();
wrong_resolution_collateral.outputs_mut()[output_base + 2].amount = Some(601);
assert_rejected(
Expand Down
2 changes: 2 additions & 0 deletions crates/deadcat-contracts/simplicityhl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ static instance facts such as:

- valid and distinct collateral, outcome-token, and RT asset identities;
- a valid oracle public key;
- correct derivation of both oracle messages from the outcome-token identities
and the protocol domain;
- correct derivation of the public RT commitments from the RT asset IDs;
- a positive base payout whose per-pair collateral is representable; and
- an expiry value with the advertised block-height semantics.
Expand Down
27 changes: 6 additions & 21 deletions crates/deadcat-contracts/simplicityhl/binary_market.simf
Original file line number Diff line number Diff line change
Expand Up @@ -410,29 +410,14 @@ fn ensure_rt_burn(
// Oracle authorization
// -----------------------------------------------------------------------------

fn compute_market_id() -> u256 {
let ctx: Ctx8 = jet::sha_256_ctx_8_init();
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, param::YES_TOKEN_ASSET_ID);
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, param::NO_TOKEN_ASSET_ID);
jet::sha_256_ctx_8_finalize(ctx)
}

fn oracle_domain() -> u256 {
// SHA256("deadcat/oracle_attestation")
0x8b96c12d4ff2c6dba7c14f5491b04200c86acf64283662940f700ad3b8b83c39
}

fn verify_oracle(outcome_yes: bool, signature: Signature) {
let outcome: u8 = match outcome_yes {
true => 1,
false => 0,
// These messages are derived by the compiler from the canonical outcome
// asset IDs and oracle domain; they are not independently selectable
// public market parameters.
let message: u256 = match outcome_yes {
true => param::ORACLE_MESSAGE_YES,
false => param::ORACLE_MESSAGE_NO,
};
let ctx: Ctx8 = jet::sha_256_ctx_8_init();
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, oracle_domain());
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, oracle_domain());
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, compute_market_id());
let ctx: Ctx8 = jet::sha_256_ctx_8_add_1(ctx, outcome);
let message: u256 = jet::sha_256_ctx_8_finalize(ctx);
jet::bip_0340_verify((param::ORACLE_PUBLIC_KEY, message), signature);
}

Expand Down
35 changes: 32 additions & 3 deletions crates/deadcat-contracts/src/binary_market/compiled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use thiserror::Error;
use super::{BinaryMarketEconomics, BinaryMarketParams, BinaryMarketSlot};
use crate::artifacts::binary_market::{BinaryMarketProgram, derived_binary_market};
use crate::finalized_spend::{FinalizedSimplicitySpend, FinalizedSimplicitySpendError};
use crate::market_crypto::{BinaryOutcome as OracleOutcome, oracle_message};
use crate::rt::{RtCommitmentError, RtLeg, RtSide, commitments, factors};

const NUMS_INTERNAL_KEY: [u8; 32] = [
Expand Down Expand Up @@ -439,8 +440,20 @@ fn contract_arguments(
) -> Result<derived_binary_market::BinaryMarketArguments, CompiledBinaryMarketError> {
let yes = rt_commitment_arguments(params.yes_reissuance_token_id, RtLeg::Yes)?;
let no = rt_commitment_arguments(params.no_reissuance_token_id, RtLeg::No)?;
let oracle_message_yes = oracle_message(
params.yes_token_asset_id,
params.no_token_asset_id,
OracleOutcome::Yes,
);
let oracle_message_no = oracle_message(
params.yes_token_asset_id,
params.no_token_asset_id,
OracleOutcome::No,
);
Ok(derived_binary_market::BinaryMarketArguments {
oracle_public_key: params.oracle_public_key,
oracle_message_yes,
oracle_message_no,
collateral_asset_id: params.collateral_asset_id.into_inner().to_byte_array(),
yes_token_asset_id: params.yes_token_asset_id.into_inner().to_byte_array(),
no_token_asset_id: params.no_token_asset_id.into_inner().to_byte_array(),
Expand Down Expand Up @@ -900,6 +913,22 @@ mod tests {
compiled.arguments.oracle_public_key,
params.oracle_public_key
);
assert_eq!(
compiled.arguments.oracle_message_yes,
oracle_message(
params.yes_token_asset_id,
params.no_token_asset_id,
OracleOutcome::Yes,
)
);
assert_eq!(
compiled.arguments.oracle_message_no,
oracle_message(
params.yes_token_asset_id,
params.no_token_asset_id,
OracleOutcome::No,
)
);
assert_eq!(
compiled.arguments.collateral_asset_id,
params.collateral_asset_id.into_inner().to_byte_array()
Expand Down Expand Up @@ -1014,9 +1043,9 @@ mod tests {
assert_eq!(
first.cmr(),
[
0xe8, 0x91, 0x2f, 0x8e, 0x5d, 0xeb, 0x3c, 0x04, 0xba, 0x47, 0xea, 0xac, 0xac, 0xc8,
0xd1, 0x94, 0xae, 0x04, 0x73, 0xe3, 0x5c, 0xee, 0x9e, 0x17, 0x1b, 0x8a, 0x71, 0xe3,
0x51, 0x3a, 0xbc, 0xa0,
0x70, 0x2f, 0x5d, 0x04, 0xf1, 0x5b, 0xcd, 0xec, 0x3f, 0xa1, 0x07, 0x05, 0x40, 0xbf,
0x2f, 0x68, 0xc0, 0xec, 0xdc, 0xf4, 0x0b, 0xc8, 0xaa, 0x80, 0x24, 0xe1, 0xe7, 0x7e,
0xf1, 0x9c, 0xd5, 0xee,
]
);

Expand Down
2 changes: 2 additions & 0 deletions crates/deadcat-contracts/tests/fixtures/binary_market_abi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ NO_RT_ASSET_B_X: u256
NO_RT_VALUE_PARITY: bool
NO_RT_VALUE_X: u256
NO_TOKEN_ASSET_ID: u256
ORACLE_MESSAGE_NO: u256
ORACLE_MESSAGE_YES: u256
ORACLE_PUBLIC_KEY: u256
YES_REISSUANCE_TOKEN_ID: u256
YES_RT_ASSET_A_PARITY: bool
Expand Down
48 changes: 33 additions & 15 deletions crates/deadcat-contracts/tests/golden_vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fmt::Write as _;
use deadcat_contracts::binary_market::{
BinaryMarketProgram, BinaryMarketSlot, CompiledBinaryMarket,
};
use deadcat_contracts::market_crypto::{BinaryOutcome as OracleOutcome, oracle_message};
use deadcat_contracts::rt::{ABF_A, ABF_B, RtLeg, RtSide, YES_CBF, commitments, factors, no_cbf};
use deadcat_types::BinaryMarketParams;
use elements::AssetId;
Expand Down Expand Up @@ -73,10 +74,27 @@ fn nonuniform_contract_arguments_compile_to_stable_cmr() {
// Every asset byte is position-sensitive. This golden therefore changes if
// `contract_arguments` accidentally substitutes display order for consensus
// byte order before compiling the parameterized program.
let compiled = CompiledBinaryMarket::new(nonuniform_params()).expect("compile market");
let params = nonuniform_params();
assert_eq!(
hex(&oracle_message(
params.yes_token_asset_id,
params.no_token_asset_id,
OracleOutcome::Yes,
)),
"0091d6c79a16ced37737ac34a7a461359d93ce1eebebca50eefd9197a1bc0876"
);
assert_eq!(
hex(&oracle_message(
params.yes_token_asset_id,
params.no_token_asset_id,
OracleOutcome::No,
)),
"10c3d52c18c0a9d2d1d9cd90dc1ae4537ad53cf2e2a4e980b5dd4f04b5f1263e"
);
let compiled = CompiledBinaryMarket::new(params).expect("compile market");
assert_eq!(
hex(&compiled.cmr()),
"2d350901b53cfeb3204f97e7708980fd62bf24914bf8e4aafb6530ce025dbb7f"
"090548f91e2f07d2e691216336b578bf15fcdbde96f2e4255e4e70c60e4c1931"
);
}

Expand Down Expand Up @@ -225,40 +243,40 @@ fn sample_binary_market_consensus_vectors_are_stable() {
let compiled = CompiledBinaryMarket::new(params).expect("compile market");
assert_eq!(
hex(&compiled.cmr()),
"e8912f8e5deb3c04ba47eaacacc8d194ae0473e35cee9e171b8a71e3513abca0"
"702f5d04f15bcdec3fa1070540bf2f68c0ecdcf40bc8aa8024e1e77ef19cd5ee"
);
let expected_slots = [
(
"51203fbf4e0e02df806affc1f0c66180a2d49b2ec03e1848a5ab326700157a7a15bd",
"512001d36e8c57cfcd1f3c2f17fb588985f8dcd5834e9938c4f7d35e3ef2a4e5acf7",
"be50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac03491a3e42d2db13335d900b3cbadcb0d5088b4eb9073869ff309910862294069",
),
(
"51206126a2324335d42fe5b9998579b9187b2b6af2a1ffa3e9e10042fc856ebc708c",
"be50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac09c44e27f20b80c93313762a6f4e71fc82db38469d90f902bc1720755b61660f3",
"5120d33c3880d2a6c1fb3a95b359fd7d602a793a10e2af5da30806685bb2c50c8390",
"bf50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac09c44e27f20b80c93313762a6f4e71fc82db38469d90f902bc1720755b61660f3",
),
(
"5120a252a8b117ebdd1bf207f98a6c2034344119d492f84d03e7052c103c1dfad71b",
"51208e9a829d1fb7d7c0cb19d524cb469dbe4e248744304f60c1bb487676ba660de5",
"be50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac04bbdde171ae4fa8cfe1c7790ec1d737b4044251c647103b3e2c320a25a8b61e2",
),
(
"51207bea2e337f0bb4f7235a16a61b8aa2935fcbc011d423ebcda8c3f0f7d4456d35",
"5120a4e68ecf6a94a73272c75e2023f9ab3cd3fd1ce0e86e5556540ce33bec5739b1",
"bf50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac013169a5cae722314cc26e3f278b4f9d087affe9b0dab437d6d8c2b28ace343d0",
),
(
"5120b1920be3d3c368dd49067dd3958bd1c5c79af3166ba5534d34ddf2a6e087e68a",
"51208745d41c870ac38b4aa9d9c9bf345f160a9e82f1691daa50216a79a224b6b7ea",
"be50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac04b7b02768d8d3b9339bfd3417355db78cada99eb21f1e32873b3ab77065ee015",
),
(
"5120fccd0ab4351768ecf55fbf7cbe2bb65591845bdc13978e8b5832de33f87afa74",
"be50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac094c17910e4ec9a08d1a445308fd4b66ee01cc818d1772a8deff59dd38b649bee",
"512098e5b0dc5969b4f0716f179507d882026857b84f507692da10d258081ff979f1",
"bf50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac094c17910e4ec9a08d1a445308fd4b66ee01cc818d1772a8deff59dd38b649bee",
),
(
"51206b247f70cbae80525455896174fb5d3129d417b224418650bd7d6e444dd8a4c7",
"be50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0838594e38820be8487ed62ea7663c1d3ce2f20b3f0c7d8075b1bd3f436239d25",
"5120ba9e2e04ae3c5b62b8a2eba46eddb764d7d2038f2640a6db0654ee9d52e793ac",
"bf50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0838594e38820be8487ed62ea7663c1d3ce2f20b3f0c7d8075b1bd3f436239d25",
),
(
"51208e44c81c10c744ea9d5ab30469e1c1510e5a67c08c42a10db2973c9f876f91bb",
"be50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac03efb3634a85ea11aa3a246775edf9406ff088af069350d5b8a4ef7a9f862ae0c",
"51200a566889ec9ce31dea29985827ae10915373de02c609285b4d735b04880d7338",
"bf50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac03efb3634a85ea11aa3a246775edf9406ff088af069350d5b8a4ef7a9f862ae0c",
),
];
for (slot, (script, control_block)) in BinaryMarketSlot::ALL.into_iter().zip(expected_slots) {
Expand Down
Loading
Loading