From badec07d85d0106e9850d9792fc53a5f38d7a2ba Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Thu, 12 Oct 2023 09:49:57 +0200 Subject: [PATCH] feat: proof checking and relay init --- script/Bridge.s.sol | 22 +++++++++++- sdk/package.json | 4 ++- sdk/scripts/init-bridge.ts | 54 +++++++++++++++++++++++++++++ sdk/src/electrs.ts | 5 +++ src/bridge/BitcoinTx.sol | 6 ++++ src/bridge/IRelay.sol | 3 ++ src/relay/DummyRelay.sol | 28 +++++++++++++++ src/relay/LightRelay.sol | 5 +++ src/swap/Bridge.sol | 28 +++++---------- src/swap/Btc_Marketplace.sol | 16 +++++++-- src/swap/Marketplace.sol | 61 ++++++++++----------------------- test/BitcoinTx.t.sol | 2 +- test/LightRelay.t.sol | 22 ++++-------- test/swap/Bridge.t.sol | 39 +++++---------------- test/swap/Btc_Marketplace.t.sol | 50 +++++++++------------------ test/swap/Marketplace.t.sol | 3 +- test/swap/Utilities.sol | 5 +-- 17 files changed, 201 insertions(+), 152 deletions(-) create mode 100644 sdk/scripts/init-bridge.ts create mode 100644 src/relay/DummyRelay.sol diff --git a/script/Bridge.s.sol b/script/Bridge.s.sol index 7cb37a1a..047784fe 100644 --- a/script/Bridge.s.sol +++ b/script/Bridge.s.sol @@ -2,11 +2,31 @@ pragma solidity ^0.8.13; import {Script, console2} from "forge-std/Script.sol"; +import "../src/relay/LightRelay.sol"; contract BridgeScript is Script { function setUp() public {} function run() public { - vm.broadcast(); + bytes memory data = + hex"04000000473ed7b7ef2fce828c318fd5e5868344a5356c9e93b6040400000000000000004409cae5b7b2f8f18ea55f558c9bfa7c5f4778a1a53172a48fc57e172d0ed3d264c5eb56c3a40618af9bc1c7"; + uint256 height = 403200; + + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + bytes memory genesisHeader = vm.envBytes("GENESIS_HEADER"); + uint256 genesisHeight = vm.envUint("GENESIS_HEIGHT"); + bytes memory retargetHeaders = vm.envBytes("RETARGET_HEADERS"); + + vm.startBroadcast(deployerPrivateKey); + LightRelay relay = new LightRelay(); + + // Initialize relay at the given block + relay.genesis(genesisHeader, genesisHeight, 1); + + // submit retarget + relay.retarget(retargetHeaders); + + vm.stopBroadcast(); } } diff --git a/sdk/package.json b/sdk/package.json index c8f4981d..cf0b2537 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -4,6 +4,7 @@ "main": "index.js", "scripts": { "test": "ts-mocha test/*.ts", + "deploy-relay": "ts-node scripts/init-bridge.ts", "build": "tsc" }, "devDependencies": { @@ -14,7 +15,8 @@ "mocha": "^10.2.0", "ts-mocha": "^10.0.0", "ts-node-dev": "^2.0.0", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "yargs": "^17.5.1" }, "dependencies": { "bitcoinjs-lib": "^6.1.5" diff --git a/sdk/scripts/init-bridge.ts b/sdk/scripts/init-bridge.ts new file mode 100644 index 00000000..7c93db50 --- /dev/null +++ b/sdk/scripts/init-bridge.ts @@ -0,0 +1,54 @@ +/* eslint @typescript-eslint/no-var-requires: "off" */ + +import { DefaultElectrsClient } from "../src/electrs"; +const yargs = require("yargs/yargs"); +const { hideBin } = require("yargs/helpers"); +const { exec } = require('child_process'); + +const args = yargs(hideBin(process.argv)) + .option("init-height", { + description: "Height of the bitcoin chain to initialize the relay at", + type: "number", + demandOption: true, + }) + .option("private-key", { + description: "Private key to submit with", + type: "string", + demandOption: true, + }).argv; +main().catch((err) => { + console.log("Error thrown by script:"); + console.log(err); +}); + + +async function main(): Promise { + const electrs = new DefaultElectrsClient("testnet"); + // args["parachain-endpoint"] + + const initHeight = args["init-height"]; + const privateKey = args["private-key"]; + if ((initHeight % 2016) != 0) { + throw new Error("Invalid genesis height: must be multiple of 2016"); + } + + const genesis = await electrs.getBlockHeaderAt(initHeight); + + const beforeRetarget = await electrs.getBlockHeaderAt(initHeight + 2015); + const afterRetarget = await electrs.getBlockHeaderAt(initHeight + 2016); + + console.log(`Genesis: ${genesis}`); + console.log(`beforeRetarget: ${beforeRetarget}`); + console.log(`afterRetarget: ${afterRetarget}`); + + + exec(`GENESIS_HEIGHT=${initHeight} GENESIS_HEADER=${genesis} RETARGET_HEADERS=${beforeRetarget}${afterRetarget} PRIVATE_KEY=${privateKey} forge script script/Bridge.s.sol:BridgeScript --rpc-url 'https://l2-fluffy-bob-7mjgi9pmtg.t.conduit.xyz' --chain 901 --verify --verifier blockscout --verifier-url 'https://explorerl2-fluffy-bob-7mjgi9pmtg.t.conduit.xyz/api?' --broadcast`, + (err: any, stdout: any, stderr: any) => { + if (err) { + throw new Error(`Failed to run command: ${err}`); + } + + // the *entire* stdout and stderr (buffered) + console.log(`stdout: ${stdout}`); + }); +} diff --git a/sdk/src/electrs.ts b/sdk/src/electrs.ts index 63ca5b7d..604bca03 100644 --- a/sdk/src/electrs.ts +++ b/sdk/src/electrs.ts @@ -63,6 +63,11 @@ export class DefaultElectrsClient implements ElectrsClient { return this.getText(`${this.basePath}/block/${hash}/header`); } + async getBlockHeaderAt(height: number): Promise { + const blockHash = await this.getBlockHash(height); + return await this.getBlockHeader(blockHash); + } + async getTransactionHex(txId: string): Promise { return this.getText(`${this.basePath}/tx/${txId}/hex`); } diff --git a/src/bridge/BitcoinTx.sol b/src/bridge/BitcoinTx.sol index 40790a8c..71c89dc2 100644 --- a/src/bridge/BitcoinTx.sol +++ b/src/bridge/BitcoinTx.sol @@ -184,6 +184,12 @@ library BitcoinTx { bytes memory bitcoinHeaders ) internal view { IRelay relay = self.relay; + + // for testing + if (!relay.difficultyCheckEnabled()) { + return; + } + uint256 currentEpochDifficulty = relay.getCurrentEpochDifficulty(); uint256 previousEpochDifficulty = relay.getPrevEpochDifficulty(); diff --git a/src/bridge/IRelay.sol b/src/bridge/IRelay.sol index 6d18d24f..43e47573 100644 --- a/src/bridge/IRelay.sol +++ b/src/bridge/IRelay.sol @@ -14,4 +14,7 @@ interface IRelay { /// @notice Returns the difficulty of the previous epoch. function getPrevEpochDifficulty() external view returns (uint256); + + /// @notice Returns true iff difficulty check should be performed. + function difficultyCheckEnabled() external view returns (bool); } diff --git a/src/relay/DummyRelay.sol b/src/relay/DummyRelay.sol new file mode 100644 index 00000000..2e02b6a4 --- /dev/null +++ b/src/relay/DummyRelay.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0-only + +// Forked from https://github.com/keep-network/tbtc-v2 + +pragma solidity 0.8.17; + +import "@openzeppelin/contracts/access/Ownable.sol"; + +import {BytesLib} from "@bob-collective/bitcoin-spv/BytesLib.sol"; +import {BTCUtils} from "@bob-collective/bitcoin-spv/BTCUtils.sol"; +import {ValidateSPV} from "@bob-collective/bitcoin-spv/ValidateSPV.sol"; + +import "../bridge/IRelay.sol"; + +/// @dev DEV-only! +contract DummyRelay is IRelay { + function getCurrentEpochDifficulty() external view returns (uint256) { + return 0; + } + + function getPrevEpochDifficulty() external view returns (uint256) { + return 0; + } + + function difficultyCheckEnabled() external view returns (bool) { + return false; + } +} diff --git a/src/relay/LightRelay.sol b/src/relay/LightRelay.sol index 4c0bf27a..6a412fd8 100644 --- a/src/relay/LightRelay.sol +++ b/src/relay/LightRelay.sol @@ -550,6 +550,11 @@ contract LightRelay is Ownable, ILightRelay { return (currentEpochDifficulty, prevEpochDifficulty); } + function difficultyCheckEnabled() external view returns (bool) { + return true; + } + + /// @notice Get the difficulty of the specified epoch. /// @param epochNumber The number of the epoch (the height of the first /// block of the epoch, divided by 2016). Must fall within the relay range. diff --git a/src/swap/Bridge.sol b/src/swap/Bridge.sol index 9365ae5d..f6121bbd 100644 --- a/src/swap/Bridge.sol +++ b/src/swap/Bridge.sol @@ -20,9 +20,11 @@ contract Bridge { address accepterAddress; BitcoinAddress bitcoinAddress; } + struct BitcoinAddress { uint256 bitcoinAddress; // todo: use the right type } + struct TransactionProof { // todo: fields here uint256 dummy; @@ -43,11 +45,7 @@ contract Bridge { } /// request zBTC to be redeemed for given amount of BTC. - function requestSwap( - uint256 amountZbtc, - uint256 amountBtc, - BitcoinAddress calldata bitcoinAddress - ) public { + function requestSwap(uint256 amountZbtc, uint256 amountBtc, BitcoinAddress calldata bitcoinAddress) public { // lock Zbtc by transfering it to the contract address wrapped.sudoTransferFrom(msg.sender, address(this), amountZbtc); require(amountZbtc != 0); @@ -79,14 +77,11 @@ contract Bridge { require(order.requesterAddress == msg.sender); // ensure the request was not accepted yet require(order.accepterAddress == address(0)); - + delete orders[id]; } - function executeSwap( - uint256 id, - TransactionProof calldata transactionProof - ) public { + function executeSwap(uint256 id, TransactionProof calldata transactionProof) public { // todo: check proof // move the zbtc thta was locked to whoever accepted the order @@ -96,10 +91,7 @@ contract Bridge { require(!order.open); require(order.amountZbtc != 0); - wrapped.transfer( - order.accepterAddress, - order.amountZbtc - ); + wrapped.transfer(order.accepterAddress, order.amountZbtc); // clean up storage delete orders[id]; @@ -119,18 +111,16 @@ contract Bridge { uint256 totalZbtc = wrapped.totalSupply(); uint256 requiredCol = btcToCol(totalZbtc * collateralThreshold); uint256 colFree = totalCollateral - requiredCol; - uint256 withdrawal = colFree < suppliedCollateral[msg.sender] - ? colFree - : suppliedCollateral[msg.sender]; + uint256 withdrawal = colFree < suppliedCollateral[msg.sender] ? colFree : suppliedCollateral[msg.sender]; suppliedCollateral[msg.sender] -= withdrawal; totalCollateral -= withdrawal; } - function colToBtc(uint256 collateral) internal pure returns (uint) { + function colToBtc(uint256 collateral) internal pure returns (uint256) { return collateral / 5; // todo } - function btcToCol(uint256 collateral) internal pure returns (uint) { + function btcToCol(uint256 collateral) internal pure returns (uint256) { return collateral * 5; // todo } } diff --git a/src/swap/Btc_Marketplace.sol b/src/swap/Btc_Marketplace.sol index d0c54461..da7d15dd 100644 --- a/src/swap/Btc_Marketplace.sol +++ b/src/swap/Btc_Marketplace.sol @@ -3,10 +3,15 @@ pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {BitcoinTx} from "../bridge/BitcoinTx.sol"; +// import {LightRelay} from "../relay/LightRelay.sol"; +import {IRelay} from "../bridge/IRelay.sol"; +import {BridgeState} from "../bridge/BridgeState.sol"; using SafeERC20 for IERC20; contract BtcMarketPlace { + using BitcoinTx for BridgeState.Storage; + mapping(uint256 => BtcBuyOrder) public btcBuyOrders; mapping(uint256 => AcceptedBtcBuyOrder) public acceptedBtcBuyOrders; mapping(uint256 => BtcSellOrder) public btcSellOrders; @@ -15,6 +20,13 @@ contract BtcMarketPlace { uint256 nextOrderId; uint256 public constant REQUEST_EXPIRATION_SECONDS = 6 hours; + BridgeState.Storage internal relay; + + constructor(IRelay _relay) { + relay.relay = _relay; + relay.txProofDifficultyFactor = 1; // will make this an arg later on + } + // todo: should we merge buy&sell structs? They're structurally identical except for the // bitcoinaddress location. @@ -172,7 +184,7 @@ contract BtcMarketPlace { require(accept.requester == msg.sender); - // todo: check proof + relay.validateProof(transaction, proof); IERC20(accept.ercToken).safeTransfer( accept.requester, @@ -293,7 +305,7 @@ contract BtcMarketPlace { require(accept.accepter == msg.sender); - // todo: check proof + relay.validateProof(transaction, proof); IERC20(accept.ercToken).safeTransfer(accept.accepter, accept.ercAmount); diff --git a/src/swap/Marketplace.sol b/src/swap/Marketplace.sol index 7f4ef899..43f24584 100644 --- a/src/swap/Marketplace.sol +++ b/src/swap/Marketplace.sol @@ -9,20 +9,15 @@ contract MarketPlace { mapping(uint256 => Order) public ercErcOrders; // cant have struct as key, nor tupple event placeOrder( - uint indexed orderId, + uint256 indexed orderId, address indexed requesterAddress, uint256 offeringAmount, address offeringToken, uint256 askingAmount, address askingToken ); - event acceptOrder( - uint indexed orderId, - address indexed who, - uint buyAmount, - uint saleAmount - ); - event withdrawOrder(uint indexed orderId); + event acceptOrder(uint256 indexed orderId, address indexed who, uint256 buyAmount, uint256 saleAmount); + event withdrawOrder(uint256 indexed orderId); uint256 public nextOrderId; @@ -34,23 +29,16 @@ contract MarketPlace { address requesterAddress; } - function placeErcErcOrder( - address sellingToken, - uint saleAmount, - address buyingToken, - uint buyAmount - ) public { + function placeErcErcOrder(address sellingToken, uint256 saleAmount, address buyingToken, uint256 buyAmount) + public + { require(sellingToken != address(0x0)); require(buyingToken != address(0x0)); // "lock" selling token by transferring to contract - IERC20(sellingToken).safeTransferFrom( - msg.sender, - address(this), - saleAmount - ); + IERC20(sellingToken).safeTransferFrom(msg.sender, address(this), saleAmount); - uint id = nextOrderId++; + uint256 id = nextOrderId++; Order memory order = Order({ offeringAmount: saleAmount, offeringToken: sellingToken, @@ -62,16 +50,11 @@ contract MarketPlace { ercErcOrders[id] = order; emit placeOrder( - id, - order.requesterAddress, - order.offeringAmount, - order.offeringToken, - order.askingAmount, - order.askingToken + id, order.requesterAddress, order.offeringAmount, order.offeringToken, order.askingAmount, order.askingToken ); } - function acceptErcErcOrder(uint id, uint saleAmount) public { + function acceptErcErcOrder(uint256 id, uint256 saleAmount) public { Order memory order = ercErcOrders[id]; // make sure the storage item exists @@ -79,8 +62,7 @@ contract MarketPlace { require(saleAmount <= order.askingAmount); // todo: make this safe - uint buyAmount = (saleAmount * order.offeringAmount) / - order.askingAmount; + uint256 buyAmount = (saleAmount * order.offeringAmount) / order.askingAmount; assert(saleAmount > 0); assert(buyAmount > 0); @@ -89,24 +71,17 @@ contract MarketPlace { ercErcOrders[id].offeringAmount -= buyAmount; ercErcOrders[id].askingAmount -= saleAmount; - IERC20(order.askingToken).safeTransferFrom( - msg.sender, - order.requesterAddress, - saleAmount - ); + IERC20(order.askingToken).safeTransferFrom(msg.sender, order.requesterAddress, saleAmount); IERC20(order.offeringToken).safeTransfer(msg.sender, buyAmount); emit acceptOrder(id, msg.sender, buyAmount, saleAmount); } - function withdrawErcErcOrder(uint id) public { + function withdrawErcErcOrder(uint256 id) public { Order memory order = ercErcOrders[id]; require(order.requesterAddress == msg.sender); - IERC20(order.offeringToken).safeTransfer( - msg.sender, - order.offeringAmount - ); + IERC20(order.offeringToken).safeTransfer(msg.sender, order.offeringAmount); delete ercErcOrders[id]; @@ -114,15 +89,15 @@ contract MarketPlace { } function getOpenOrders() external view returns (Order[] memory) { - uint numOpenOrders = 0; - for (uint i = 0; i < nextOrderId; i++) { + uint256 numOpenOrders = 0; + for (uint256 i = 0; i < nextOrderId; i++) { if (ercErcOrders[i].offeringAmount > 0) { numOpenOrders++; } } Order[] memory ret = new Order[](numOpenOrders); - uint numPushed = 0; - for (uint i = 0; i < nextOrderId; i++) { + uint256 numPushed = 0; + for (uint256 i = 0; i < nextOrderId; i++) { if (ercErcOrders[i].offeringAmount > 0) { ret[numPushed] = ercErcOrders[i]; numPushed++; diff --git a/test/BitcoinTx.t.sol b/test/BitcoinTx.t.sol index 92925eb8..9a9795bc 100644 --- a/test/BitcoinTx.t.sol +++ b/test/BitcoinTx.t.sol @@ -6,7 +6,7 @@ import {Test, console2} from "forge-std/Test.sol"; import {BitcoinTx} from "../src/bridge/BitcoinTx.sol"; contract BitcoinTxTest is Test { - function test_GetTxOutputValue() public { + function test_GetTxOutputValue() public { // b1273a6c00eba20ee8837e445599d1362e005f6e1a8525802ba57bc515461a3a uint64 value = BitcoinTx.getTxOutputValue( keccak256(hex"16001493adab0a7a8cb7675db135c9c97e81942025c2c9"), diff --git a/test/LightRelay.t.sol b/test/LightRelay.t.sol index 81538dbc..b2c2d5f5 100644 --- a/test/LightRelay.t.sol +++ b/test/LightRelay.t.sol @@ -58,22 +58,17 @@ contract LightRelayTest is Test { function setUp() public { relay = new LightRelay(); - relay.genesis( - genesisHeader.data, - genesisHeader.height, - 2 - ); + relay.genesis(genesisHeader.data, genesisHeader.height, 2); state.relay = relay; state.txProofDifficultyFactor = 2; // we need at least one retarget vm.warp(1459492475); - relay.retarget(abi.encodePacked( - retargetHeaders[0].data, - retargetHeaders[1].data, - retargetHeaders[2].data, - retargetHeaders[3].data - )); + relay.retarget( + abi.encodePacked( + retargetHeaders[0].data, retargetHeaders[1].data, retargetHeaders[2].data, retargetHeaders[3].data + ) + ); } function test_Retarget() public { @@ -93,10 +88,7 @@ contract LightRelayTest is Test { BitcoinTx.Proof({ merkleProof: hex"0465f99dbe384bbc5d86a5242712e4154958e4b01f595f14b76f873ec349e14a16b17770af2bb48c9b2ce4dddf4631866fe3753e6c54bdcf18dfb2d4fb9983ee58e4f3be92087c843b815bbe1d5d686dc972552f7ffda4342319ceb5bea67ab0f2e463ec8ce8e3f580c5e2470ef20c5b33398ab9fea5ccbd0b3e3f6211305edafa068a28c8ac634df5bbc8064357295373b97db2600745f23ad6ebc87b66b4a8685aa8ff8e69abc5029dbf4b2fa03f05680c7a2c491410b23a5a6b27c5a91b89dac8cdd16a4460ce8ac8d17491025d29336440a133867f938a7f41cc7a64f3f04ac3817c3eb6a6a11dc30850ca4e80f9abbd42268bcc626138bc01639a902713425e7d3aca45647001fb32ff396c07027c5b081325530e74f936e6c4a8078a05f9717efd315534a84d047ee2ff0b2b93159a2b98eabb578af67ef7540a58e488b9c587a994c1a9a86937ad343ea734b7427678e3e6ba0be8f5045ce47e541bbc", txIndexInBlock: 1, - bitcoinHeaders: abi.encodePacked( - proofHeaders[0].data, - proofHeaders[1].data - ) + bitcoinHeaders: abi.encodePacked(proofHeaders[0].data, proofHeaders[1].data) }) ); } diff --git a/test/swap/Bridge.t.sol b/test/swap/Bridge.t.sol index f025a1cb..be2fb205 100644 --- a/test/swap/Bridge.t.sol +++ b/test/swap/Bridge.t.sol @@ -32,23 +32,13 @@ contract BridgeTest is Bridge, Test { vm.deal(alice, _amount); vm.startPrank(alice); uint256 balanceBefore = address(this).balance; - (bool _success, ) = address(this).call{value: _amount}( - abi.encodeWithSignature("mint()", alice) - ); + (bool _success,) = address(this).call{value: _amount}(abi.encodeWithSignature("mint()", alice)); assertTrue(_success, "deposited payment."); // zbtc minted - assertEqDecimal( - wrapped.balanceOf(alice), - _amount / 5 / 2, - wrapped.decimals() - ); + assertEqDecimal(wrapped.balanceOf(alice), _amount / 5 / 2, wrapped.decimals()); // col has been transferred to contract - assertEqDecimal( - address(this).balance, - balanceBefore + _amount, - wrapped.decimals() - ); + assertEqDecimal(address(this).balance, balanceBefore + _amount, wrapped.decimals()); } function testLiquidate() public { @@ -56,20 +46,14 @@ contract BridgeTest is Bridge, Test { vm.deal(alice, _amount); vm.startPrank(alice); - (bool _success, ) = address(this).call{value: _amount}( - abi.encodeWithSignature("mint()", alice) - ); + (bool _success,) = address(this).call{value: _amount}(abi.encodeWithSignature("mint()", alice)); assertTrue(_success); // liquidate 25% of what was minted assertEqDecimal(wrapped.balanceOf(alice), 100, wrapped.decimals()); this.liquidate(25); assertEqDecimal(wrapped.balanceOf(alice), 75, wrapped.decimals()); - assertEqDecimal( - address(alice).balance, - btcToCol(25), - wrapped.decimals() - ); + assertEqDecimal(address(alice).balance, btcToCol(25), wrapped.decimals()); } function testWithdraw() public { @@ -77,16 +61,11 @@ contract BridgeTest is Bridge, Test { vm.deal(alice, _amount); vm.startPrank(alice); - (bool _success, ) = address(this).call{value: _amount}( - abi.encodeWithSignature("mint()", alice) - ); + (bool _success,) = address(this).call{value: _amount}(abi.encodeWithSignature("mint()", alice)); assertTrue(_success); assertEq(collateralThreshold, 2); - stdstore - .target(address(this)) - .sig(this.collateralThreshold.selector) - .checked_write(1); + stdstore.target(address(this)).sig(this.collateralThreshold.selector).checked_write(1); assertEq(collateralThreshold, 1); // sanity check that writing to storage worked uint256 lockedBefore = suppliedCollateral[alice]; @@ -102,9 +81,7 @@ contract BridgeTest is Bridge, Test { vm.deal(alice, amountCol); vm.startPrank(alice); - (bool _success, ) = address(this).call{value: amountCol}( - abi.encodeWithSignature("mint()", alice) - ); + (bool _success,) = address(this).call{value: amountCol}(abi.encodeWithSignature("mint()", alice)); assertTrue(_success, "deposited payment."); BitcoinAddress memory btcAddress = BitcoinAddress({bitcoinAddress: 1}); diff --git a/test/swap/Btc_Marketplace.t.sol b/test/swap/Btc_Marketplace.t.sol index e43c2ab8..30fcaa63 100644 --- a/test/swap/Btc_Marketplace.t.sol +++ b/test/swap/Btc_Marketplace.t.sol @@ -9,12 +9,10 @@ import {stdStorage, StdStorage, Test, console} from "forge-std/Test.sol"; import {BtcMarketPlace} from "../../src/swap/Btc_Marketplace.sol"; import {Utilities} from "./Utilities.sol"; import {BitcoinTx} from "../../src/bridge/BitcoinTx.sol"; +import {DummyRelay} from "../../src/relay/DummyRelay.sol"; contract ArbitaryErc20 is ERC20, Ownable { - constructor( - string memory name_, - string memory symbol_ - ) ERC20(name_, symbol_) {} + constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {} function sudoMint(address to, uint256 amount) public onlyOwner { _mint(to, amount); @@ -29,7 +27,7 @@ contract MarketPlaceTest is BtcMarketPlace, Test { ArbitaryErc20 token1; - constructor() BtcMarketPlace() {} + constructor() BtcMarketPlace(new DummyRelay()) {} function setUp() public { utils = new Utilities(); @@ -44,22 +42,23 @@ contract MarketPlaceTest is BtcMarketPlace, Test { } function dummyTransaction() public view returns (BitcoinTx.Info memory) { - BitcoinTx.Info memory transaction = BitcoinTx.Info({ - version: hex"00000002", - inputVector: hex"", - outputVector: hex"", + return BitcoinTx.Info({ + version: hex"01000000", + inputVector: hex"01996cf4e2f0016a1f092aaaba653c7eae5dd4b6eef1f9a2a94c64f34b2fecbd85010000006a47304402206f99da49ce586528ed8981842df30b4a5a91195fd2d83e440d4193fc16a944ec022055cfdf63a2c90638821f1b5ff1fdf77526163ae057a0d0de30a6e1d3009e7a29012102811832eef7216470f489991f1d87e36d2890755d2bbf827eb1e71804491506afffffffff", + outputVector: hex"0200e9a435000000001976a914fd7e6999cd7e7114383e014b7e612a88ab6be68f88ac804a5d05000000001976a9145c1addbd0e4e78479e71fdca0555d2d44b67378e88ac", locktime: hex"00000000" }); - return transaction; } function dummyProof() public view returns (BitcoinTx.Proof memory) { - BitcoinTx.Proof memory transaction = BitcoinTx.Proof({ - merkleProof: hex"", - txIndexInBlock: 0, - bitcoinHeaders: hex"" + return BitcoinTx.Proof({ + merkleProof: hex"0465f99dbe384bbc5d86a5242712e4154958e4b01f595f14b76f873ec349e14a16b17770af2bb48c9b2ce4dddf4631866fe3753e6c54bdcf18dfb2d4fb9983ee58e4f3be92087c843b815bbe1d5d686dc972552f7ffda4342319ceb5bea67ab0f2e463ec8ce8e3f580c5e2470ef20c5b33398ab9fea5ccbd0b3e3f6211305edafa068a28c8ac634df5bbc8064357295373b97db2600745f23ad6ebc87b66b4a8685aa8ff8e69abc5029dbf4b2fa03f05680c7a2c491410b23a5a6b27c5a91b89dac8cdd16a4460ce8ac8d17491025d29336440a133867f938a7f41cc7a64f3f04ac3817c3eb6a6a11dc30850ca4e80f9abbd42268bcc626138bc01639a902713425e7d3aca45647001fb32ff396c07027c5b081325530e74f936e6c4a8078a05f9717efd315534a84d047ee2ff0b2b93159a2b98eabb578af67ef7540a58e488b9c587a994c1a9a86937ad343ea734b7427678e3e6ba0be8f5045ce47e541bbc", + txIndexInBlock: 1, + bitcoinHeaders: abi.encodePacked( + hex"04000000e0879a33a87bf9481385adae91fa9e93713b932cbe8a09030000000000000000ee5ded948d805bb71bee5de25b447c42527898cac93eee1afe04663bb8204b358627fe56f4960618304a7db1", + hex"04000000c0de92e7326cb020b59ffc5998405e539863c57da088a7040000000000000000d8e7273d0198ba4f10dfd57d151327c32113fc244fd0587d161a5c5332a53651ed28fe56f4960618b24502cc" + ) }); - return transaction; } function testSellBtc() public { @@ -115,12 +114,7 @@ contract MarketPlaceTest is BtcMarketPlace, Test { vm.startPrank(alice); token1.approve(address(this), 100); - this.placeBtcBuyOrder( - 1000, - BitcoinAddress({bitcoinAddress: ""}), - address(token1), - 100 - ); + this.placeBtcBuyOrder(1000, BitcoinAddress({bitcoinAddress: ""}), address(token1), 100); vm.startPrank(bob); this.acceptBtcBuyOrder(0, 40); @@ -136,12 +130,7 @@ contract MarketPlaceTest is BtcMarketPlace, Test { vm.startPrank(alice); token1.approve(address(this), 100); - this.placeBtcBuyOrder( - 1000, - BitcoinAddress({bitcoinAddress: ""}), - address(token1), - 100 - ); + this.placeBtcBuyOrder(1000, BitcoinAddress({bitcoinAddress: ""}), address(token1), 100); vm.startPrank(bob); this.acceptBtcBuyOrder(0, 40); @@ -159,12 +148,7 @@ contract MarketPlaceTest is BtcMarketPlace, Test { vm.startPrank(alice); token1.approve(address(this), 100); - this.placeBtcBuyOrder( - 1000, - BitcoinAddress({bitcoinAddress: ""}), - address(token1), - 100 - ); + this.placeBtcBuyOrder(1000, BitcoinAddress({bitcoinAddress: ""}), address(token1), 100); vm.startPrank(bob); this.acceptBtcBuyOrder(0, 40); diff --git a/test/swap/Marketplace.t.sol b/test/swap/Marketplace.t.sol index 812023a3..1056a0e3 100644 --- a/test/swap/Marketplace.t.sol +++ b/test/swap/Marketplace.t.sol @@ -58,7 +58,7 @@ contract MarketPlaceTest is MarketPlace, Test { assertEq(token1.balanceOf(bob), 600); assertEq(token2.balanceOf(bob), 40); } - + function testPartialSwap() public { token1.sudoMint(alice, 1000); token2.sudoMint(bob, 100); @@ -84,7 +84,6 @@ contract MarketPlaceTest is MarketPlace, Test { token1.approve(address(this), 1000); this.placeErcErcOrder(address(token1), 1000, address(token2), 100); - assertEq(token1.balanceOf(alice), 0); this.withdrawErcErcOrder(0); assertEq(token1.balanceOf(alice), 1000); diff --git a/test/swap/Utilities.sol b/test/swap/Utilities.sol index 93d545b2..737b3cff 100644 --- a/test/swap/Utilities.sol +++ b/test/swap/Utilities.sol @@ -17,10 +17,7 @@ contract Utilities is DSTest { } //create users with 100 ether balance - function createUsers(uint256 userNum) - external - returns (address payable[] memory) - { + function createUsers(uint256 userNum) external returns (address payable[] memory) { address payable[] memory users = new address payable[](userNum); for (uint256 i = 0; i < userNum; i++) { address payable user = this.getNextUserAddress();