Skip to content

Commit

Permalink
feat: change abi of proof verification
Browse files Browse the repository at this point in the history
  • Loading branch information
reednaa committed Feb 25, 2024
1 parent 1c3e002 commit 032bb7b
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 60 deletions.
22 changes: 8 additions & 14 deletions src/BtcTxVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ contract BtcTxVerifier is IBtcTxVerifier {
uint256 blockNum,
BtcTxProof calldata inclusionProof,
uint256 txOutIx,
bytes calldata outputScript,
uint256 amountSats
) external view returns (bool) {
bytes calldata outputScript
) external view returns (uint256 sats) {
{
uint256 currentHeight = mirror.getLatestBlockHeight();

Expand All @@ -36,17 +35,12 @@ contract BtcTxVerifier is IBtcTxVerifier {

bytes32 blockHash = mirror.getBlockHash(blockNum);

if(
!BtcProof.validateExactOut(
blockHash,
inclusionProof,
txOutIx,
outputScript,
amountSats
)
) revert InvalidProof();

return true;
return sats = BtcProof.validateExactOut(
blockHash,
inclusionProof,
txOutIx,
outputScript
);
}

function verifyOrdinal(
Expand Down
5 changes: 2 additions & 3 deletions src/interfaces/IBtcTxVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ interface IBtcTxVerifier {
uint256 blockNum,
BtcTxProof calldata inclusionProof,
uint256 txOutIx,
bytes calldata outputScript,
uint256 amountSats
) external view returns (bool);
bytes calldata outputScript
) external view returns (uint256 amountSats);

/** @notice Returns the underlying mirror associated with this verifier. */
function mirror() external view returns (IBtcPrism);
Expand Down
14 changes: 5 additions & 9 deletions src/library/BtcProof.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ library BtcProof {
* @dev Validates that a given payment appears under a given block hash.
*
* This verifies all of the following:
* 1. Raw transaction contains a transcation that pay X satoshis to the specified output script
* 1. Raw transaction contains an output to the specified output script
* 2. Raw transaction hashes to the given transaction ID.
* 3. Transaction ID appears under transaction root (Merkle proof).
* 4. Transaction root is part of the block header.
Expand All @@ -34,9 +34,8 @@ library BtcProof {
bytes32 blockHash,
BtcTxProof calldata txProof,
uint256 txOutIx,
bytes calldata outputScript,
uint256 satoshisExpected
) internal pure returns (bool) {
bytes calldata outputScript
) internal pure returns (uint256) {
// 5. Block header to block hash

bytes32 blockHeaderBlockHash = getBlockHash(txProof.blockHeader);
Expand Down Expand Up @@ -64,11 +63,8 @@ library BtcProof {
} else {
if (keccak256(txo.script) != keccak256(outputScript)) revert ScriptMismatch(txo.script, outputScript);
}
if (txo.valueSats != satoshisExpected) revert AmountMismatch(txo.valueSats, satoshisExpected);

// We've verified that blockHash contains a transaction with correct script
// that sends at least satoshisExpected to the given hash.
return true;
// We've verified that blockHash contains a transaction with an output to the correct script.
return txo.valueSats;
}

/**
Expand Down
39 changes: 13 additions & 26 deletions test/BtcProof.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ contract MockBtcProof {
bytes32 blockHash,
BtcTxProof calldata txProof,
uint256 txOutIx,
bytes calldata outputScript,
uint256 satoshisExpected
) external pure returns (bool) {
return BtcProof.validateExactOut(blockHash, txProof, txOutIx, outputScript, satoshisExpected);
bytes calldata outputScript
) external pure returns (uint256) {
return BtcProof.validateExactOut(blockHash, txProof, txOutIx, outputScript);
}

function getBlockHash(bytes calldata blockHeader)
Expand Down Expand Up @@ -301,11 +300,14 @@ contract BtcProofTest is DSTest {
bytes memory destScript = hex"a914ae2f3d4b06579b62574d6178c10c882b9150374087";

// Should succeed
BtcProofUtils.validateExactOut(
uint256 measuredOut = BtcProofUtils.validateExactOut(
blockHash736000,
BtcTxProof(header736000, txId736, 1, txProof736, tx736),
0,
destScript,
destScript
);
assertEq(
measuredOut,
25200000
);

Expand All @@ -315,8 +317,7 @@ contract BtcProofTest is DSTest {
blockHash717695,
BtcTxProof(header736000, txId736, 1, txProof736, tx736),
0,
destScript,
25200000
destScript
);

// - Bad tx proof (doesn't match root)
Expand All @@ -325,8 +326,7 @@ contract BtcProofTest is DSTest {
blockHash717695,
BtcTxProof(headerGood, txId736, 1, txProof736, tx736),
0,
destScript,
25200000
destScript
);

// - Wrong tx index
Expand All @@ -335,8 +335,7 @@ contract BtcProofTest is DSTest {
blockHash736000,
BtcTxProof(header736000, txId736, 2, txProof736, tx736),
0,
destScript,
25200000
destScript
);

// - Wrong tx output index
Expand All @@ -345,8 +344,7 @@ contract BtcProofTest is DSTest {
blockHash736000,
BtcTxProof(header736000, txId736, 1, txProof736, tx736),
1,
destScript,
25200000
destScript
);

// - Wrong dest script hash
Expand All @@ -355,18 +353,7 @@ contract BtcProofTest is DSTest {
blockHash736000,
BtcTxProof(header736000, txId736, 1, txProof736, tx736),
0,
hex"abcd",
25200000
);

// - Wrong amount, off by one satoshi
vm.expectRevert(abi.encodeWithSelector(AmountMismatch.selector, 25200000, 25200001));
BtcProofUtils.validateExactOut(
blockHash736000,
BtcTxProof(header736000, txId736, 1, txProof736, tx736),
0,
destScript,
25200001
hex"abcd"
);
}
}
13 changes: 5 additions & 8 deletions test/BtcTxVerifier.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,16 @@ contract BtcTxVerifierTest is DSTest {
tx736
);

assertTrue(verif.verifyPayment(1, 736000, txP, 0, destScript, 25200000));
assertEq(verif.verifyPayment(1, 736000, txP, 0, destScript), 25200000);

vm.expectRevert(abi.encodeWithSelector(TooFewConfirmations.selector, 1, 2));
assertTrue(!verif.verifyPayment(2, 736000, txP, 0, destScript, 25200000));

vm.expectRevert(abi.encodeWithSelector(AmountMismatch.selector, 25200000, 25200001));
assertTrue(!verif.verifyPayment(1, 736000, txP, 0, destScript, 25200001));
assertEq(verif.verifyPayment(2, 736000, txP, 0, destScript), 0);

vm.expectRevert(abi.encodeWithSelector(ScriptMismatch.selector, hex"a91415ecf89e95eb07fbc351b3f7f4c54406f7ee5c1087", hex"a914ae2f3d4b06579b62574d6178c10c882b9150374087"));
assertTrue(!verif.verifyPayment(1, 736000, txP, 1, destScript, 25200000));
assertEq(verif.verifyPayment(1, 736000, txP, 1, destScript), 0);

vm.expectRevert(abi.encodeWithSelector(BlockHashMismatch.selector, 0x00000000000000000002d52d9816a419b45f1f0efe9a9df4f7b64161e508323d, 0x0000000000000000000000000000000000000000000000000000000000000000));
assertTrue(!verif.verifyPayment(1, 700000, txP, 0, destScript, 25200000));
assertEq(verif.verifyPayment(1, 700000, txP, 0, destScript), 0);
}

function testVerifySegwitTx() public {
Expand Down Expand Up @@ -149,6 +146,6 @@ contract BtcTxVerifierTest is DSTest {
tx39
);

assertTrue(verif.verifyPayment(1, 831400, txP, 0, destScript, 3270000));
assertEq(verif.verifyPayment(1, 831400, txP, 0, destScript), 3270000);
}
}

0 comments on commit 032bb7b

Please sign in to comment.