Skip to content

Commit

Permalink
Make tests work after migration
Browse files Browse the repository at this point in the history
  • Loading branch information
okkothejawa committed Apr 1, 2024
1 parent d76d11c commit aedc02a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
19 changes: 3 additions & 16 deletions crates/evm/src/evm/system_contracts/src/Bridge.sol
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "openzeppelin-contracts/contracts/access/Ownable.sol";
import "bitcoin-spv/solidity/contracts/ValidateSPV.sol";
import "bitcoin-spv/solidity/contracts/BTCUtils.sol";

import "./MerkleTree.sol";
import "./IL1BlockHashList.sol";
import "./L1BlockHashList.sol";

/// @title Bridge contract of Clementine
/// @author Citrea

contract Bridge is MerkleTree, Ownable {
// TODO: Update this to be the actual address of the L1BlockHashList contract
IL1BlockHashList public constant BLOCK_HASH_LIST = IL1BlockHashList(address(0xdeaddeaddeaddeaddeaddeaddeaddeaddeaddead));
L1BlockHashList public constant BLOCK_HASH_LIST = L1BlockHashList(address(0xdeaDDeADDEaDdeaDdEAddEADDEAdDeadDEADDEaD));

bytes public DEPOSIT_TXOUT_0 = hex"c2ddf50500000000225120fc6eb6fa4fd4ed1e8519a7edfa171eddcedfbd0e0be49b5e531ef36e7e66eb05";
uint256 public constant DEPOSIT_AMOUNT = 1 ether;
Expand All @@ -32,7 +31,7 @@ contract Bridge is MerkleTree, Ownable {
_;
}

constructor(uint32 _levels) MerkleTree(_levels) Ownable(msg.sender) {}
constructor(uint32 _levels) MerkleTree(_levels) {}

/// @notice Sets the expected first transaction output of a deposit transaction on Bitcoin, which signifies the multisig address on Bitcoin
/// @dev TxOut0 is derived from the multisig on Bitcoin so it stays constant as long as the multisig doesn't change
Expand Down Expand Up @@ -106,25 +105,13 @@ contract Bridge is MerkleTree, Ownable {
}
}

/// @notice Checks if passed in Bitcoin block hash exists in the list of block hashes
/// @param block_hash The queried block hash
function isCorrectBlockHash(bytes32 block_hash) public view returns (bool) {
return blockHashes[block_hash];
}

/// @notice Adds a block hash to the list of block hashes
/// @param block_hash The block hash to be added
function addBlockHash(bytes32 block_hash) external onlyOwner {
blockHashes[block_hash] = true;
emit BlockHashAdded(block_hash);
}

/// @notice Checks if passed in Bitcoin block hash exists in the list of block hashes
/// @param block_hash The queried block hash
function isCorrectBlockHash(bytes32 block_hash) public view returns (bool) {
return blockHashes[block_hash];
}

/// @notice Sets the operator address that can process user deposits
/// @param _operator Address of the privileged operator
function setOperator(address _operator) external onlyOwner {
Expand Down
40 changes: 23 additions & 17 deletions crates/evm/src/evm/system_contracts/test/Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,25 @@ contract BridgeTest is Test {
address operator = makeAddr("citrea_operator");
address user = makeAddr("citrea_user");

uint256 constant INITIAL_BLOCK_NUMBER = 505050;
bytes32 randomMerkleRoot = bytes32(keccak256("CITREA"));

function setUp() public {
bridge = new BridgeHarness(31);
vm.deal(address(bridge), 21_000_000 ether);
address block_hash_list_impl = address(new L1BlockHashList());
L1BlockHashList l1BlockHashList = bridge.BLOCK_HASH_LIST();
vm.etch(address(l1BlockHashList), block_hash_list_impl.code);

address self = address(this);
vm.startPrank(address(0));
l1BlockHashList.transferOwnership(self);
vm.stopPrank();
l1BlockHashList.acceptOwnership();

l1BlockHashList.initializeBlockNumber(INITIAL_BLOCK_NUMBER);
bytes32 expected_blockhash = hex"b25d57f9acbf22e533b0963b47d91b11bdef9da9591002b1ef4e3ef856aec80e";
// Owner adds the expected block hash of the block as an accepted block hash containing the transaction above
bridge.addBlockHash(expected_blockhash);
l1BlockHashList.setBlockInfo(expected_blockhash, randomMerkleRoot);
}

function testZeros() public {
Expand All @@ -56,7 +68,7 @@ contract BridgeTest is Test {
// Operator makes a deposit for the `receiver` address specified in the second output of above Bitcoin txn
bridge.setOperator(operator);
vm.startPrank(operator);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);

bytes memory output2 = BTCUtils.extractOutputAtIndex(vout, 1);
bytes memory output2_ext = BTCUtils.extractOpReturnData(output2);
Expand All @@ -72,7 +84,7 @@ contract BridgeTest is Test {
// Operator makes a deposit for the `receiver` address specified in the second output of above Bitcoin txn
bridge.setOperator(operator);
vm.startPrank(operator);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);

bytes memory output2 = BTCUtils.extractOutputAtIndex(vout, 1);
bytes memory output2_ext = BTCUtils.extractOpReturnData(output2);
Expand Down Expand Up @@ -128,32 +140,32 @@ contract BridgeTest is Test {
function testCannotDoubleDepositWithSameTx() public {
bridge.setOperator(operator);
vm.startPrank(operator);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);
vm.expectRevert("txId already spent");
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);
}

function testCannotDepositWithFalseProof() public {
vin = hex"1234";
bridge.setOperator(operator);
vm.startPrank(operator);
vm.expectRevert("SPV Verification failed.");
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);
}

function testCannotDepositWithFalseBlockHash() public {
block_header = hex"1234";
bridge.setOperator(operator);
vm.startPrank(operator);
vm.expectRevert("incorrect block hash");
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
vm.expectRevert("Incorrect block hash");
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);
}

function testCannotWithdrawWithInvalidAmount() public {
// Operator makes a deposit for the `receiver` address specified in the second output of above Bitcoin txn
bridge.setOperator(operator);
vm.startPrank(operator);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);

bytes memory output2 = BTCUtils.extractOutputAtIndex(vout, 1);
bytes memory output2_ext = BTCUtils.extractOpReturnData(output2);
Expand All @@ -172,7 +184,7 @@ contract BridgeTest is Test {

function testNonOperatorCannotDeposit() public {
vm.expectRevert("caller is not the operator");
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, index);
bridge.deposit(version, vin, vout, locktime, intermediate_nodes, block_header, INITIAL_BLOCK_NUMBER, index);
}

function testCannotSetOperatorIfNotOwner() public {
Expand Down Expand Up @@ -210,12 +222,6 @@ contract BridgeTest is Test {
assertEq(isKeccakEqual(a, a), bridge.isBytesEqual_(a, a));
}

function testAddBlockHash() public {
bytes32 block_hash = hex"1234";
bridge.addBlockHash(block_hash);
assert(bridge.isCorrectBlockHash(block_hash));
}

function testSetDepositTxOut0() public {
bytes memory depositTxOut0 = hex"1234";
bridge.setDepositTxOut0(depositTxOut0);
Expand Down

0 comments on commit aedc02a

Please sign in to comment.