Skip to content

Commit

Permalink
feat: minor fixes after review
Browse files Browse the repository at this point in the history
  • Loading branch information
ferencdg committed Jul 29, 2024
1 parent 92684ce commit 899e151
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 80 deletions.
92 changes: 13 additions & 79 deletions src/utils/BitcoinTx.sol
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,6 @@ library BitcoinTx {
);
}

/// @notice Type of data after the OP_RETURN code
enum OutputType {
EVM_ADDRESS,
HASH
}

/// @notice Represents temporary information needed during the processing of
/// the Bitcoin transaction outputs. This structure is an internal one
/// and should not be exported outside of the transaction processing code.
Expand All @@ -217,84 +211,28 @@ library BitcoinTx {
uint256 outputStartingIndex;
// The number of outputs in the transaction.
uint256 outputsCount;
// The type of data after the OP_RETURN code.
OutputType outputType;
}

/// @notice Represents an outcome of the Bitcoin transaction
/// outputs processing potentially containing evm address.
/// outputs processing.
struct TxOutputsInfo {
// Sum of all outputs values spending to the output.
uint64 value;
// Optional EVM address specified in OP_RETURN.
address evmAddress;
}

/// @notice Represents an outcome of the Bitcoin transaction
/// outputs processing potentially containing 32 byte hash.
struct TxOutputsInfoHash {
// Sum of all outputs values spending to the output.
uint64 value;
// Optional hash specified in OP_RETURN.
bytes32 hash;
}

/// @notice Represents an outcome of the Bitcoin transaction
/// outputs processing including either evm address or 32 bytes hash.
struct ExtendedTxOutputsInfo {
// Sum of all outputs values spending to the output.
uint64 value;
// Optional EVM address specified in OP_RETURN.
address evmAddress;
// Optional hash specified in OP_RETURN.
bytes32 hash;
}

/// @notice Processes the Bitcoin transaction output vector potentially containing EVM address.
/// @param txOutputVector Bitcoin transaction output vector.
/// This function assumes vector's structure is valid so it
/// must be validated using e.g. `BTCUtils.validateVout` function
/// before it is passed here.
/// @param scriptPubKeyHash Expected Bitcoin scriptPubKey keccak256 hash.
/// @return resultInfo Outcomes of the processing.
function processTxOutputs(bytes memory txOutputVector, bytes32 scriptPubKeyHash)
internal
pure
returns (TxOutputsInfo memory resultInfo)
{
ExtendedTxOutputsInfo memory extendedResultInfo =
processTxOutputs(txOutputVector, scriptPubKeyHash, OutputType.EVM_ADDRESS);
return TxOutputsInfo(extendedResultInfo.value, extendedResultInfo.evmAddress);
}

/// @notice Processes the Bitcoin transaction output vector potentially containing 32 byte hash.
/// @param txOutputVector Bitcoin transaction output vector.
/// This function assumes vector's structure is valid so it
/// must be validated using e.g. `BTCUtils.validateVout` function
/// before it is passed here.
/// @param scriptPubKeyHash Expected Bitcoin scriptPubKey keccak256 hash.
/// @return resultInfo Outcomes of the processing.
function processTxOutputsHash(bytes memory txOutputVector, bytes32 scriptPubKeyHash)
internal
pure
returns (TxOutputsInfoHash memory resultInfo)
{
ExtendedTxOutputsInfo memory extendedResultInfo =
processTxOutputs(txOutputVector, scriptPubKeyHash, OutputType.HASH);
return TxOutputsInfoHash(extendedResultInfo.value, extendedResultInfo.hash);
}

/// @notice Processes all outputs from the transaction.
/// @param txOutputVector Bitcoin transaction output vector. This function
/// assumes vector's structure is valid so it must be validated using
/// e.g. `BTCUtils.validateVout` function before it is passed here.
/// @param scriptPubKeyHash Expected Bitcoin scriptPubKey keccak256 hash.
/// @param outputType The type of extra data in the UTXO for example evm address or hash
/// starting index and the number of outputs.
function processTxOutputs(bytes memory txOutputVector, bytes32 scriptPubKeyHash, OutputType outputType)
function processTxOutputs(bytes memory txOutputVector, bytes32 scriptPubKeyHash)
internal
pure
returns (ExtendedTxOutputsInfo memory resultInfo)
returns (TxOutputsInfo memory resultInfo)
{
// needed to avoid stack too deep errors
TxOutputsProcessingInfo memory processInfo;
Expand All @@ -319,7 +257,6 @@ library BitcoinTx {
// Please refer `BTCUtils` library and compactSize uint
// docs in `BitcoinTx` library for more details.
processInfo.outputStartingIndex++;
processInfo.outputType = outputType;

// Helper flag indicating whether there was at least one
// output present
Expand Down Expand Up @@ -355,19 +292,16 @@ library BitcoinTx {
// payments to the same output
resultInfo.value += outputValue;
} else {
if (processInfo.outputType == OutputType.EVM_ADDRESS) {
address outputEvmAddress =
extractEvmAddressFromOutput(txOutputVector, processInfo.outputStartingIndex);
if (outputEvmAddress != address(0)) {
// NOTE: this will overwrite if there are multiple OP_RETURN outputs
resultInfo.evmAddress = outputEvmAddress;
}
} else if (processInfo.outputType == OutputType.HASH) {
bytes32 outputHash = extractHashFromOutput(txOutputVector, processInfo.outputStartingIndex);
if (outputHash != 0) {
// NOTE: this will overwrite if there are multiple OP_RETURN outputs
resultInfo.hash = outputHash;
}
address outputEvmAddress = extractEvmAddressFromOutput(txOutputVector, processInfo.outputStartingIndex);
if (outputEvmAddress != address(0)) {
// NOTE: this will overwrite if there are multiple OP_RETURN outputs
resultInfo.evmAddress = outputEvmAddress;
}

bytes32 outputHash = extractHashFromOutput(txOutputVector, processInfo.outputStartingIndex);
if (outputHash != 0) {
// NOTE: this will overwrite if there are multiple OP_RETURN outputs
resultInfo.hash = outputHash;
}
}

Expand Down
11 changes: 10 additions & 1 deletion test/BitcoinTx.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,21 @@ contract BitcoinTxTest is Test {
assertFalse(success);
}

function test_ProcessTxOutputsWithOpReturn() public {
function test_ProcessTxOutputsWithOpReturnAddress() public {
BitcoinTx.TxOutputsInfo memory resultInfo = BitcoinTx.processTxOutputs(
hex"02983a000000000000146142b39c0073672dc382b89a42b29e06368bcabd0000000000000000166a14675ca18a04027fd50c88ccd03939e0e5c97b795f",
keccak256(hex"146142b39c0073672dc382b89a42b29e06368bcabd")
);
assertEq(resultInfo.value, 15000);
assertEq(resultInfo.evmAddress, 0x675Ca18A04027fd50C88CcD03939E0e5C97b795f);
}

function test_ProcessTxOutputsWithOpReturnBytes32() public {
BitcoinTx.TxOutputsInfo memory resultInfo = BitcoinTx.processTxOutputs(
hex"02983a000000000000146142b39c0073672dc382b89a42b29e06368bcabd0000000000000000166a2000112233445566778899001122334455667788990011",
keccak256(hex"146142b39c0073672dc382b89a42b29e06368bcabd")
);
assertEq(resultInfo.value, 15000);
assertEq(resultInfo.hash, hex"00112233445566778899001122334455667788990011");
}
}

0 comments on commit 899e151

Please sign in to comment.