Result<(), Error> {
+ pub fn store_payout_proof(
+ e: &Env,
+ release: bool,
+ proof: Bytes,
+ remaining_blinding: soroban_sdk::BytesN<32>,
+ ) -> Result<(), Error> {
let esc = get(e);
esc.depositor.require_auth();
if esc.state != EscrowState::Created {
@@ -128,7 +133,14 @@ impl PrivateEscrowInstance {
} else {
&esc.depositor
};
- if !token(e).verify_escrow_payout(®ister_data, &auditor_id, &transfer_in, to, &proof) {
+ if !token(e).verify_escrow_payout(
+ ®ister_data,
+ &auditor_id,
+ &transfer_in,
+ to,
+ &proof,
+ &remaining_blinding,
+ ) {
return Err(Error::InvalidPayoutProof);
}
let key = if release {
diff --git a/contracts/escrow-instance/src/lib.rs b/contracts/escrow-instance/src/lib.rs
index 6bb5ff4..2c06c69 100644
--- a/contracts/escrow-instance/src/lib.rs
+++ b/contracts/escrow-instance/src/lib.rs
@@ -48,6 +48,7 @@ pub trait ConfidentialTokenInterface {
transfer_in: Bytes,
to: Address,
data: Bytes,
+ remaining_blinding: soroban_sdk::BytesN<32>,
) -> bool;
}
diff --git a/contracts/escrow-instance/src/test.rs b/contracts/escrow-instance/src/test.rs
index e945d1d..dbd91e9 100644
--- a/contracts/escrow-instance/src/test.rs
+++ b/contracts/escrow-instance/src/test.rs
@@ -33,6 +33,7 @@ impl MockToken {
transfer_in: Bytes,
_to: Address,
data: Bytes,
+ _remaining_blinding: soroban_sdk::BytesN<32>,
) -> bool {
!data.is_empty() && data == transfer_in
}
@@ -131,8 +132,16 @@ fn b(f: &Fixture) -> Bytes {
fn fund(f: &Fixture) {
f.escrow.prepare_funding(&b(f), &0u32, &b(f));
- f.escrow.store_payout_proof(&true, &b(f));
- f.escrow.store_payout_proof(&false, &b(f));
+ f.escrow.store_payout_proof(
+ &true,
+ &b(f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32]),
+ );
+ f.escrow.store_payout_proof(
+ &false,
+ &b(f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32]),
+ );
f.escrow.fund();
}
@@ -261,8 +270,16 @@ fn fund_before_payout_proofs_blocked() {
fn preparing_again_invalidates_both_payout_proofs() {
let f = setup(false);
f.escrow.prepare_funding(&b(&f), &0u32, &b(&f));
- f.escrow.store_payout_proof(&true, &b(&f));
- f.escrow.store_payout_proof(&false, &b(&f));
+ f.escrow.store_payout_proof(
+ &true,
+ &b(&f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32]),
+ );
+ f.escrow.store_payout_proof(
+ &false,
+ &b(&f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32]),
+ );
f.escrow.prepare_funding(&b(&f), &1u32, &b(&f));
assert_eq!(f.escrow.try_fund(), Err(Ok(Error::PayoutProofsMissing)));
}
@@ -351,8 +368,12 @@ fn stranger_cannot_mark_completed() {
e.mock_all_auths();
let blob = Bytes::from_array(&e, &[1]);
escrow.prepare_funding(&blob, &0u32, &blob);
- escrow.store_payout_proof(&true, &blob);
- escrow.store_payout_proof(&false, &blob);
+ escrow.store_payout_proof(&true, &blob, &soroban_sdk::BytesN::from_array(&e, &[0; 32]));
+ escrow.store_payout_proof(
+ &false,
+ &blob,
+ &soroban_sdk::BytesN::from_array(&e, &[0; 32]),
+ );
escrow.fund();
// Real auth required now: nobody authorized as the recipient.
@@ -364,16 +385,28 @@ fn stranger_cannot_mark_completed() {
fn invalid_release_proof_cannot_enable_funding() {
let f = setup(false);
f.escrow.prepare_funding(&b(&f), &0u32, &b(&f));
- f.escrow.store_payout_proof(&false, &b(&f));
+ f.escrow.store_payout_proof(
+ &false,
+ &b(&f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32]),
+ );
assert_eq!(
- f.escrow.try_store_payout_proof(&true, &Bytes::new(&f.e)),
+ f.escrow.try_store_payout_proof(
+ &true,
+ &Bytes::new(&f.e),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32])
+ ),
Err(Ok(Error::InvalidPayoutProof))
);
assert_eq!(f.escrow.try_fund(), Err(Ok(Error::PayoutProofsMissing)));
assert_eq!(f.escrow.get_escrow().state, EscrowState::Created);
assert!(MockTokenClient::new(&f.e, &f.token).xfers().is_empty());
// A corrected proof can be submitted before funding, with no funds at risk.
- f.escrow.store_payout_proof(&true, &b(&f));
+ f.escrow.store_payout_proof(
+ &true,
+ &b(&f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32]),
+ );
f.escrow.fund();
}
@@ -381,10 +414,17 @@ fn invalid_release_proof_cannot_enable_funding() {
fn invalid_refund_proof_cannot_enable_funding() {
let f = setup(false);
f.escrow.prepare_funding(&b(&f), &0u32, &b(&f));
- f.escrow.store_payout_proof(&true, &b(&f));
+ f.escrow.store_payout_proof(
+ &true,
+ &b(&f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32]),
+ );
assert_eq!(
- f.escrow
- .try_store_payout_proof(&false, &Bytes::from_array(&f.e, &[1])),
+ f.escrow.try_store_payout_proof(
+ &false,
+ &Bytes::from_array(&f.e, &[1]),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32])
+ ),
Err(Ok(Error::InvalidPayoutProof))
);
assert_eq!(f.escrow.try_fund(), Err(Ok(Error::PayoutProofsMissing)));
@@ -394,7 +434,11 @@ fn invalid_refund_proof_cannot_enable_funding() {
fn payout_proof_requires_prepared_inputs() {
let f = setup(false);
assert_eq!(
- f.escrow.try_store_payout_proof(&true, &b(&f)),
+ f.escrow.try_store_payout_proof(
+ &true,
+ &b(&f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32])
+ ),
Err(Ok(Error::FundingNotPrepared))
);
}
@@ -427,7 +471,11 @@ fn cannot_replace_prepared_inputs_or_proofs_after_funding() {
Err(Ok(Error::BadState))
);
assert_eq!(
- f.escrow.try_store_payout_proof(&true, &b(&f)),
+ f.escrow.try_store_payout_proof(
+ &true,
+ &b(&f),
+ &soroban_sdk::BytesN::from_array(&f.e, &[0; 32])
+ ),
Err(Ok(Error::BadState))
);
}
diff --git a/contracts/escrow-instance/test_snapshots/test/cannot_fund_twice.1.json b/contracts/escrow-instance/test_snapshots/test/cannot_fund_twice.1.json
index 3c21317..6bb6d09 100644
--- a/contracts/escrow-instance/test_snapshots/test/cannot_fund_twice.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/cannot_fund_twice.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/cannot_replace_prepared_inputs_or_proofs_after_funding.1.json b/contracts/escrow-instance/test_snapshots/test/cannot_replace_prepared_inputs_or_proofs_after_funding.1.json
index 7b3c26c..68f9830 100644
--- a/contracts/escrow-instance/test_snapshots/test/cannot_replace_prepared_inputs_or_proofs_after_funding.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/cannot_replace_prepared_inputs_or_proofs_after_funding.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/claim_after_window_blocked_when_arbiter_set.1.json b/contracts/escrow-instance/test_snapshots/test/claim_after_window_blocked_when_arbiter_set.1.json
index c8668d1..e9a8dcd 100644
--- a/contracts/escrow-instance/test_snapshots/test/claim_after_window_blocked_when_arbiter_set.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/claim_after_window_blocked_when_arbiter_set.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/claim_after_window_no_arbiter.1.json b/contracts/escrow-instance/test_snapshots/test/claim_after_window_no_arbiter.1.json
index 1a0b589..e3ae62d 100644
--- a/contracts/escrow-instance/test_snapshots/test/claim_after_window_no_arbiter.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/claim_after_window_no_arbiter.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/claim_before_window_blocked.1.json b/contracts/escrow-instance/test_snapshots/test/claim_before_window_blocked.1.json
index 9aa4cbe..4768937 100644
--- a/contracts/escrow-instance/test_snapshots/test/claim_before_window_blocked.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/claim_before_window_blocked.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_depositor.1.json b/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_depositor.1.json
index ddb859c..c5b732f 100644
--- a/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_depositor.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_depositor.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_recipient.1.json b/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_recipient.1.json
index f43643c..76f3f3a 100644
--- a/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_recipient.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/dispute_then_resolve_to_recipient.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/dispute_without_arbiter_blocked.1.json b/contracts/escrow-instance/test_snapshots/test/dispute_without_arbiter_blocked.1.json
index 032a4d4..2810b1f 100644
--- a/contracts/escrow-instance/test_snapshots/test/dispute_without_arbiter_blocked.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/dispute_without_arbiter_blocked.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/early_release_from_funded.1.json b/contracts/escrow-instance/test_snapshots/test/early_release_from_funded.1.json
index 7575243..65c09d1 100644
--- a/contracts/escrow-instance/test_snapshots/test/early_release_from_funded.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/early_release_from_funded.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/fund_moves_to_funded.1.json b/contracts/escrow-instance/test_snapshots/test/fund_moves_to_funded.1.json
index 7b3c26c..68f9830 100644
--- a/contracts/escrow-instance/test_snapshots/test/fund_moves_to_funded.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/fund_moves_to_funded.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/invalid_refund_proof_cannot_enable_funding.1.json b/contracts/escrow-instance/test_snapshots/test/invalid_refund_proof_cannot_enable_funding.1.json
index 1c009a6..bba953c 100644
--- a/contracts/escrow-instance/test_snapshots/test/invalid_refund_proof_cannot_enable_funding.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/invalid_refund_proof_cannot_enable_funding.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/invalid_release_proof_cannot_enable_funding.1.json b/contracts/escrow-instance/test_snapshots/test/invalid_release_proof_cannot_enable_funding.1.json
index 6357521..ed5c7b9 100644
--- a/contracts/escrow-instance/test_snapshots/test/invalid_release_proof_cannot_enable_funding.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/invalid_release_proof_cannot_enable_funding.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -72,6 +75,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/normal_release_pays_recipient.1.json b/contracts/escrow-instance/test_snapshots/test/normal_release_pays_recipient.1.json
index 88221c8..a667075 100644
--- a/contracts/escrow-instance/test_snapshots/test/normal_release_pays_recipient.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/normal_release_pays_recipient.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/preparing_again_invalidates_both_payout_proofs.1.json b/contracts/escrow-instance/test_snapshots/test/preparing_again_invalidates_both_payout_proofs.1.json
index 46b5e39..2b41cbd 100644
--- a/contracts/escrow-instance/test_snapshots/test/preparing_again_invalidates_both_payout_proofs.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/preparing_again_invalidates_both_payout_proofs.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/stranger_cannot_mark_completed.1.json b/contracts/escrow-instance/test_snapshots/test/stranger_cannot_mark_completed.1.json
index 62286f8..4042fa5 100644
--- a/contracts/escrow-instance/test_snapshots/test/stranger_cannot_mark_completed.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/stranger_cannot_mark_completed.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "01"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "01"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/timeout_blocked_after_completed.1.json b/contracts/escrow-instance/test_snapshots/test/timeout_blocked_after_completed.1.json
index a29074a..46ce156 100644
--- a/contracts/escrow-instance/test_snapshots/test/timeout_blocked_after_completed.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/timeout_blocked_after_completed.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/timeout_refunds_depositor.1.json b/contracts/escrow-instance/test_snapshots/test/timeout_refunds_depositor.1.json
index 848e277..5ba0aed 100644
--- a/contracts/escrow-instance/test_snapshots/test/timeout_refunds_depositor.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/timeout_refunds_depositor.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/timeout_too_early.1.json b/contracts/escrow-instance/test_snapshots/test/timeout_too_early.1.json
index 3c21317..6bb6d09 100644
--- a/contracts/escrow-instance/test_snapshots/test/timeout_too_early.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/timeout_too_early.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_refund.1.json b/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_refund.1.json
index a4a5c57..e903205 100644
--- a/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_refund.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_refund.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_release.1.json b/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_release.1.json
index 019ac8c..a913233 100644
--- a/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_release.1.json
+++ b/contracts/escrow-instance/test_snapshots/test/unsolicited_credit_does_not_block_release.1.json
@@ -46,6 +46,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
@@ -68,6 +71,9 @@
},
{
"bytes": "0909090909090909"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
diff --git a/contracts/token/src/escrow.rs b/contracts/token/src/escrow.rs
index f83a806..6f6927c 100644
--- a/contracts/token/src/escrow.rs
+++ b/contracts/token/src/escrow.rs
@@ -30,6 +30,7 @@ impl ConfidentialTokenContract {
transfer_in: Bytes,
to: Address,
data: Bytes,
+ remaining_blinding: soroban_sdk::BytesN<32>,
) -> bool {
let registration: RegisterData = storage::decode_data(e, ®ister_data);
let funding: TransferData = storage::decode_data(e, &transfer_in);
@@ -38,6 +39,13 @@ impl ConfidentialTokenContract {
let auditor = ConfidentialAuditorClient::new(e, &storage::get_auditor(e));
let p = &payout.payload;
+ // A general transfer proof permits a partial payout. Bind its remaining
+ // commitment to a publicly opened zero balance before accepting it.
+ if !Grumpkin::is_canonical_field(&remaining_blinding)
+ || p.c_spend_new != zero_commitment(e, &remaining_blinding)
+ {
+ return false;
+ }
let mut pi = Bytes::new(e);
append_point(&mut pi, &funding.payload.c_tx);
append_point(&mut pi, ®istration.payload.y);
@@ -74,3 +82,52 @@ fn append_field(pi: &mut Bytes, field: &BytesN<32>) {
}
pi.append(&Bytes::from(field));
}
+
+/// Compute r·H with the same independent blinding generator as the circuits.
+fn zero_commitment(e: &Env, r: &BytesN<32>) -> Point {
+ let h = BytesN::from_array(
+ e,
+ &[
+ 5, 74, 168, 106, 115, 203, 138, 52, 82, 94, 91, 190, 214, 228, 59, 161, 25, 142, 134,
+ 15, 95, 57, 80, 38, 143, 113, 223, 69, 145, 189, 228, 2, 32, 157, 207, 191, 44, 251,
+ 87, 249, 246, 4, 111, 68, 215, 26, 198, 250, 248, 114, 84, 175, 199, 64, 124, 4, 235,
+ 98, 26, 98, 135, 202, 193, 38,
+ ],
+ );
+ let mut result = Grumpkin::identity(e);
+ for byte in r.to_array() {
+ for bit in (0..8).rev() {
+ result = Grumpkin::add(e, &result, &result);
+ if byte & (1 << bit) != 0 {
+ result = Grumpkin::add(e, &result, &h);
+ }
+ }
+ }
+ result
+}
+
+#[cfg(test)]
+mod zero_tests {
+ use super::*;
+
+ #[test]
+ fn zero_opening_uses_the_circuit_blinding_generator() {
+ let e = Env::default();
+ let mut one = [0u8; 32];
+ one[31] = 1;
+ let h = zero_commitment(&e, &BytesN::from_array(&e, &one));
+ assert!(Grumpkin::is_on_curve(&e, &h));
+ assert_ne!(h, Grumpkin::generator(&e));
+ let mut two = one;
+ two[31] = 2;
+ assert_eq!(
+ zero_commitment(&e, &BytesN::from_array(&e, &two)),
+ Grumpkin::add(&e, &h, &h)
+ );
+ let large = [0x10u8; 32];
+ assert!(Grumpkin::is_on_curve(
+ &e,
+ &zero_commitment(&e, &BytesN::from_array(&e, &large))
+ ));
+ }
+}
diff --git a/contracts/token/src/test.rs b/contracts/token/src/test.rs
index 8022e42..84c3deb 100644
--- a/contracts/token/src/test.rs
+++ b/contracts/token/src/test.rs
@@ -105,7 +105,8 @@ fn setup() -> Fixture {
proof: Bytes::new(&e),
};
let funding = transfer(&e);
- let payout = transfer(&e);
+ let mut payout = transfer(&e);
+ payout.payload.c_spend_new = Grumpkin::identity(&e);
e.as_contract(&token, || {
e.storage().persistent().set(
&ConfidentialTokenStorageKey::Account(from.clone()),
@@ -151,7 +152,8 @@ fn escrow_preflight_matches_real_token_transfer_public_inputs_without_moving_fun
&1,
&f.funding.to_xdr(&f.e),
&f.to,
- &f.payout.clone().to_xdr(&f.e)
+ &f.payout.clone().to_xdr(&f.e),
+ &BytesN::from_array(&f.e, &[0; 32])
));
let expected = VerifierClient::new(&f.e, &f.verifier).inputs();
assert_eq!(
@@ -173,7 +175,8 @@ fn escrow_preflight_propagates_verifier_rejection() {
&1,
&f.funding.to_xdr(&f.e),
&f.to,
- &f.payout.to_xdr(&f.e)
+ &f.payout.to_xdr(&f.e),
+ &BytesN::from_array(&f.e, &[0; 32])
)
);
}
@@ -187,7 +190,8 @@ fn escrow_preflight_rejects_malformed_payload() {
&1,
&f.funding.to_xdr(&f.e),
&f.to,
- &Bytes::new(&f.e)
+ &Bytes::new(&f.e),
+ &BytesN::from_array(&f.e, &[0; 32])
)
.is_err());
}
@@ -202,7 +206,24 @@ fn escrow_preflight_rejects_noncanonical_public_inputs() {
&1,
&f.funding.to_xdr(&f.e),
&f.to,
- &f.payout.to_xdr(&f.e)
+ &f.payout.to_xdr(&f.e),
+ &BytesN::from_array(&f.e, &[0; 32])
)
.is_err());
}
+
+#[test]
+fn escrow_preflight_rejects_partial_payout_even_when_transfer_verifier_accepts() {
+ let mut f = setup();
+ f.payout.payload.c_spend_new = point(&f.e, 4);
+ assert!(
+ !ConfidentialTokenContractClient::new(&f.e, &f.token).verify_escrow_payout(
+ &f.registration.to_xdr(&f.e),
+ &1,
+ &f.funding.to_xdr(&f.e),
+ &f.to,
+ &f.payout.to_xdr(&f.e),
+ &BytesN::from_array(&f.e, &[0; 32]),
+ )
+ );
+}
diff --git a/contracts/token/test_snapshots/test/escrow_preflight_matches_real_token_transfer_public_inputs_without_moving_funds.1.json b/contracts/token/test_snapshots/test/escrow_preflight_matches_real_token_transfer_public_inputs_without_moving_funds.1.json
index ea2f48e..931f3c4 100644
--- a/contracts/token/test_snapshots/test/escrow_preflight_matches_real_token_transfer_public_inputs_without_moving_funds.1.json
+++ b/contracts/token/test_snapshots/test/escrow_preflight_matches_real_token_transfer_public_inputs_without_moving_funds.1.json
@@ -29,7 +29,7 @@
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM"
},
{
- "bytes": "0000001100000001000000020000000f000000077061796c6f61640000000011000000010000000a0000000f00000007625f6175645f73000000000d00000020000000000000000000000000000000000000000000000000000000000000000d0000000f00000007625f74696c6465000000000d0000002000000000000000000000000000000000000000000000000000000000000000080000000f0000000b635f7370656e645f6e6577000000000d000000400213cb9d1f32d90df15ecef40edfd4b4013726c52d0583416f13b031c8f24648091b5252177dd98cbaf3fb47cf994413a7e1144f6f604c46a5bead567b51a6ec0000000f00000004635f74780000000d000000402d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c0000000f00000007725f6175645f72000000000d00000020000000000000000000000000000000000000000000000000000000000000000b0000000f00000003725f65000000000d000000402639fb5afa37f916f0abdd25fd442bc53a8f51ad105ef675d535afca07b7cd741ae7198c38ecf03a73a7b2d98df7241c46a8bd5ba45ec44dd57f8dd994a2b2760000000f000000057369676d610000000000000d0000002000000000000000000000000000000000000000000000000000000000000000090000000f00000007765f6175645f72000000000d00000020000000000000000000000000000000000000000000000000000000000000000a0000000f00000007765f6175645f73000000000d00000020000000000000000000000000000000000000000000000000000000000000000c0000000f00000007765f74696c6465000000000d0000002000000000000000000000000000000000000000000000000000000000000000070000000f0000000570726f6f660000000000000d000000012a000000"
+ "bytes": "0000001100000001000000020000000f000000077061796c6f61640000000011000000010000000a0000000f00000007625f6175645f73000000000d00000020000000000000000000000000000000000000000000000000000000000000000d0000000f00000007625f74696c6465000000000d0000002000000000000000000000000000000000000000000000000000000000000000080000000f0000000b635f7370656e645f6e6577000000000d00000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000004635f74780000000d000000402d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c0000000f00000007725f6175645f72000000000d00000020000000000000000000000000000000000000000000000000000000000000000b0000000f00000003725f65000000000d000000402639fb5afa37f916f0abdd25fd442bc53a8f51ad105ef675d535afca07b7cd741ae7198c38ecf03a73a7b2d98df7241c46a8bd5ba45ec44dd57f8dd994a2b2760000000f000000057369676d610000000000000d0000002000000000000000000000000000000000000000000000000000000000000000090000000f00000007765f6175645f72000000000d00000020000000000000000000000000000000000000000000000000000000000000000a0000000f00000007765f6175645f73000000000d00000020000000000000000000000000000000000000000000000000000000000000000c0000000f00000007765f74696c6465000000000d0000002000000000000000000000000000000000000000000000000000000000000000070000000f0000000570726f6f660000000000000d000000012a000000"
}
]
}
@@ -70,7 +70,7 @@
"symbol": "pi"
},
"val": {
- "bytes": "2d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d070f704f3760742131a62723bdaf8e9e49722a7ea0e221e2065e55a826ace71b63295c5ef57658847a467fd0bdb0182040919ea3be6242aa395c1b249e9d857dd32a69fbcbb6bf5fbe3c8d5a06237f8ce6c49d26bc26aebc0a94b3df5613263e45004be015a410fcd86f09c2cdbc243b54a6e3d7bbf9990e03a2c4868ab2a11b4a19f36003498da6ca6ea600ad31e9bda3a8f7c007b2777618f064c0bf95b9cac92eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d070213cb9d1f32d90df15ecef40edfd4b4013726c52d0583416f13b031c8f24648091b5252177dd98cbaf3fb47cf994413a7e1144f6f604c46a5bead567b51a6ec2d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2639fb5afa37f916f0abdd25fd442bc53a8f51ad105ef675d535afca07b7cd741ae7198c38ecf03a73a7b2d98df7241c46a8bd5ba45ec44dd57f8dd994a2b276000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d"
+ "bytes": "2d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d070f704f3760742131a62723bdaf8e9e49722a7ea0e221e2065e55a826ace71b63295c5ef57658847a467fd0bdb0182040919ea3be6242aa395c1b249e9d857dd32a69fbcbb6bf5fbe3c8d5a06237f8ce6c49d26bc26aebc0a94b3df5613263e45004be015a410fcd86f09c2cdbc243b54a6e3d7bbf9990e03a2c4868ab2a11b4a19f36003498da6ca6ea600ad31e9bda3a8f7c007b2777618f064c0bf95b9cac92eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2639fb5afa37f916f0abdd25fd442bc53a8f51ad105ef675d535afca07b7cd741ae7198c38ecf03a73a7b2d98df7241c46a8bd5ba45ec44dd57f8dd994a2b276000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d"
}
}
]
@@ -146,7 +146,7 @@
"symbol": "spendable_balance"
},
"val": {
- "bytes": "0213cb9d1f32d90df15ecef40edfd4b4013726c52d0583416f13b031c8f24648091b5252177dd98cbaf3fb47cf994413a7e1144f6f604c46a5bead567b51a6ec"
+ "bytes": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
{
diff --git a/contracts/token/test_snapshots/test/escrow_preflight_propagates_verifier_rejection.1.json b/contracts/token/test_snapshots/test/escrow_preflight_propagates_verifier_rejection.1.json
index 4dc8cdf..fe2a039 100644
--- a/contracts/token/test_snapshots/test/escrow_preflight_propagates_verifier_rejection.1.json
+++ b/contracts/token/test_snapshots/test/escrow_preflight_propagates_verifier_rejection.1.json
@@ -41,7 +41,7 @@
"symbol": "pi"
},
"val": {
- "bytes": "2d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d070f704f3760742131a62723bdaf8e9e49722a7ea0e221e2065e55a826ace71b63295c5ef57658847a467fd0bdb0182040919ea3be6242aa395c1b249e9d857dd32a69fbcbb6bf5fbe3c8d5a06237f8ce6c49d26bc26aebc0a94b3df5613263e45004be015a410fcd86f09c2cdbc243b54a6e3d7bbf9990e03a2c4868ab2a11b4a19f36003498da6ca6ea600ad31e9bda3a8f7c007b2777618f064c0bf95b9cac92eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d070213cb9d1f32d90df15ecef40edfd4b4013726c52d0583416f13b031c8f24648091b5252177dd98cbaf3fb47cf994413a7e1144f6f604c46a5bead567b51a6ec2d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2639fb5afa37f916f0abdd25fd442bc53a8f51ad105ef675d535afca07b7cd741ae7198c38ecf03a73a7b2d98df7241c46a8bd5ba45ec44dd57f8dd994a2b276000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d"
+ "bytes": "2d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d070f704f3760742131a62723bdaf8e9e49722a7ea0e221e2065e55a826ace71b63295c5ef57658847a467fd0bdb0182040919ea3be6242aa395c1b249e9d857dd32a69fbcbb6bf5fbe3c8d5a06237f8ce6c49d26bc26aebc0a94b3df5613263e45004be015a410fcd86f09c2cdbc243b54a6e3d7bbf9990e03a2c4868ab2a11b4a19f36003498da6ca6ea600ad31e9bda3a8f7c007b2777618f064c0bf95b9cac92eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c2639fb5afa37f916f0abdd25fd442bc53a8f51ad105ef675d535afca07b7cd741ae7198c38ecf03a73a7b2d98df7241c46a8bd5ba45ec44dd57f8dd994a2b276000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d"
}
}
]
diff --git a/contracts/token/test_snapshots/test/escrow_preflight_rejects_partial_payout_even_when_transfer_verifier_accepts.1.json b/contracts/token/test_snapshots/test/escrow_preflight_rejects_partial_payout_even_when_transfer_verifier_accepts.1.json
new file mode 100644
index 0000000..ca5572d
--- /dev/null
+++ b/contracts/token/test_snapshots/test/escrow_preflight_rejects_partial_payout_even_when_transfer_verifier_accepts.1.json
@@ -0,0 +1,307 @@
+{
+ "generators": {
+ "address": 7,
+ "nonce": 0,
+ "mux_id": 0
+ },
+ "auth": [
+ [],
+ [],
+ [],
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 26,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ {
+ "entry": {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": null
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ "live_until": 4095
+ },
+ {
+ "entry": {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": null
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ "live_until": 4095
+ },
+ {
+ "entry": {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Account"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ ]
+ },
+ "durability": "persistent",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "auditor_id"
+ },
+ "val": {
+ "u32": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "receiving_balance"
+ },
+ "val": {
+ "bytes": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "spendable_balance"
+ },
+ "val": {
+ "bytes": "2d0a8556b15580b949b5104b0c0b527ad61dac372081ec532fbccd2da8e263361725e2dd632b098eba49a7e9d310aba4843a67e4f40e2b98df1ca6fe4c57c49c"
+ }
+ },
+ {
+ "key": {
+ "symbol": "spending_key"
+ },
+ "val": {
+ "bytes": "2eff510e43fa25f29efbfd646b7ef62f11ff77a27df704e249eb061e8b1e89291495f4d469ff1a7ac1a42fef25b7e63d19862fcaf2b7cfde3a88418ebbc02d07"
+ }
+ },
+ {
+ "key": {
+ "symbol": "viewing_public_key"
+ },
+ "val": {
+ "bytes": "004be015a410fcd86f09c2cdbc243b54a6e3d7bbf9990e03a2c4868ab2a11b4a19f36003498da6ca6ea600ad31e9bda3a8f7c007b2777618f064c0bf95b9cac9"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ "live_until": 4095
+ },
+ {
+ "entry": {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Account"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM"
+ }
+ ]
+ },
+ "durability": "persistent",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "auditor_id"
+ },
+ "val": {
+ "u32": 2
+ }
+ },
+ {
+ "key": {
+ "symbol": "receiving_balance"
+ },
+ "val": {
+ "bytes": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "spendable_balance"
+ },
+ "val": {
+ "bytes": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "spending_key"
+ },
+ "val": {
+ "bytes": "0228011f2cbbd22dad3b9d335a55232bc439b6150d2411fe06b31e912125b2132cd113f3d0cbc3ff264558c0e8a89341ac983ed52d359e9f6eff12723b3f2c25"
+ }
+ },
+ {
+ "key": {
+ "symbol": "viewing_public_key"
+ },
+ "val": {
+ "bytes": "0f704f3760742131a62723bdaf8e9e49722a7ea0e221e2065e55a826ace71b63295c5ef57658847a467fd0bdb0182040919ea3be6242aa395c1b249e9d857dd3"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ "live_until": 518400
+ },
+ {
+ "entry": {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "AddressAsField"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "2a69fbcbb6bf5fbe3c8d5a06237f8ce6c49d26bc26aebc0a94b3df5613263e45"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Admin"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Auditor"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "UnderlyingAsset"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Verifier"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ "live_until": 4095
+ },
+ {
+ "entry": {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ "live_until": 4095
+ }
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/packages/app/lib/wallet.ts b/packages/app/lib/wallet.ts
index ff91e5d..35135b3 100644
--- a/packages/app/lib/wallet.ts
+++ b/packages/app/lib/wallet.ts
@@ -186,15 +186,34 @@ export class ConfidentialWallet {
// indexer (if present), so a stale deployment no longer makes sync throw.
const fromLedger: number = DEPLOYMENT.deployedAtLedger;
+ const store = new LocalStorageStore(`lucent:state:${DEPLOYMENT.networkPassphrase}:${DEPLOYMENT.contracts.token}:`);
const engine = new StateEngine({
client,
- store: new LocalStorageStore(),
+ store,
keys,
address: signer.publicKey,
fromLedger,
indexer,
});
+ // Preserve a legacy cache only when its openings and this deployment's
+ // registered keys match the chain. Never reuse its deployment-less cursor:
+ // capture a fresh chain cursor, then recheck before committing the migration.
+ if (!(await store.load(signer.publicKey))) {
+ const legacy = await new LocalStorageStore().load(signer.publicKey);
+ const acct = legacy ? await client.confidentialBalance(signer.publicKey) : null;
+ if (legacy && acct && acct.spendingKey.equals(keys.Y) && acct.viewingPublicKey.equals(keys.PVK)) {
+ const candidate = new StateEngine({ client, store: new LocalStorageStore(), keys,
+ address: signer.publicKey, fromLedger, indexer });
+ if ((await candidate.verifyAgainstChain()).ok) {
+ const tip = await hybridFetchEvents(client, undefined, { fromLedger: (await client.server.getHealth()).latestLedger });
+ if ((await candidate.verifyAgainstChain()).ok && tip.cursor) {
+ await store.save({ ...legacy, cursor: tip.cursor, syncedLedger: tip.latestLedger });
+ }
+ }
+ }
+ }
+
return new ConfidentialWallet(signer.publicKey, signer, keys, client, engine, indexer, log);
}
@@ -556,9 +575,9 @@ export class ConfidentialWallet {
transferIn,
});
this.log("validating recipient payout…");
- await submitStorePayoutProof(this.client, this.signer, instance, true, releaseProof);
+ await submitStorePayoutProof(this.client, this.signer, instance, true, releaseProof, rel.next.r);
this.log("validating refund payout…");
- await submitStorePayoutProof(this.client, this.signer, instance, false, refundProof);
+ await submitStorePayoutProof(this.client, this.signer, instance, false, refundProof, ref.next.r);
this.log("submitting fund…");
const r = await submitFund(this.client, this.signer, instance);
await this.engine.setSpendable(tin.next);
diff --git a/packages/sdk/contracts/confidential_token.wasm b/packages/sdk/contracts/confidential_token.wasm
index 6560bc7259ae7bc7ff555e77c3f089028c543967..b7ddddb9411882e6d8be259e3bd045767dc1aa1d 100644
GIT binary patch
delta 14973
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