From 0a0e1f1e4dd0bc8ea8dc35d6f3a2be8316ad0982 Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Thu, 23 Dec 2021 15:14:41 +0800 Subject: [PATCH 1/8] add sourceTokenAddress Signed-off-by: cyl19970726 <15258378443@163.com> --- contracts/app/Bridge.sol | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index feaa46d..2e42755 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -33,17 +33,24 @@ contract BridgeSource { constructor() {} function withdraw( + address sourceTokenAddress, BridgeLib.TransferData memory transferData, bytes32[] memory proof - ) public { + ) public payable{ // safemath not needed for solidity 8 uint256 amountPlusFee = (transferData.amount * (10000 + CONTRACT_FEE_BASIS_POINTS)) / 10000; - IERC20(transferData.tokenAddress).safeTransferFrom( - msg.sender, - address(this), - amountPlusFee - ); + + if (sourceTokenAddress == address(0)){ + require(msg.value >= amountPlusFee,"not enough msg.value"); + payable(sourceTokenAddress).transfer(amountPlusFee); + }else{ + IERC20(sourceTokenAddress).safeTransferFrom( + msg.sender, + address(this), + amountPlusFee + ); + } BridgeLib.TransferInitiated memory transferInitiated = BridgeLib .TransferInitiated({data: transferData, self: address(this)}); @@ -103,14 +110,20 @@ contract BridgeDestination { return 0; } - function buy(TransferKey memory tkey) public { + function buy(TransferKey memory tkey) public payable{ uint256 amount = tkey.transferData.amount - getLPFee(tkey.transferData); - // TODO: another token address on dest. chain? - IERC20(tkey.transferData.tokenAddress).safeTransferFrom( - msg.sender, - tkey.transferData.destination, - amount - ); + + if(tkey.transferData.tokenAddress == address(0)){ + require(msg.value >= amount,"not enough msg.value"); + payable(tkey.transferData.destination).transfer(amount); + }else{ + // TODO: another token address on dest. chain? + IERC20(tkey.transferData.tokenAddress).safeTransferFrom( + msg.sender, + tkey.transferData.destination, + amount + ); + } bytes32 key = keccak256(abi.encode(tkey)); require(ownerMap[key] == address(0), "already bought or withdrawn"); From bfe443fccf5046437942fb66c229d9d9af2f78b6 Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Thu, 23 Dec 2021 15:41:45 +0800 Subject: [PATCH 2/8] Add the function body to the getLPFee function Signed-off-by: cyl19970726 <15258378443@163.com> --- contracts/app/Bridge.sol | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index 2e42755..dcdfbce 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -11,6 +11,7 @@ library BridgeLib { address tokenAddress; address destination; uint256 amount; + uint256 fee; uint256 startTime; uint256 feeRampup; } @@ -106,8 +107,13 @@ contract BridgeDestination { view returns (uint256) { - // TODO: - return 0; + if (currentTime < startTime){ + return 0; + }else if(currentTime >= transferData.startTime + transferData.feeRampup){ + return transferData.fee; + }else{ + return transferData.fee * (transferData.currentTime - transferData.startTime); + } } function buy(TransferKey memory tkey) public payable{ From 3612af1a7a74e56af9a908a8a04310dfc4b0ede2 Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Thu, 23 Dec 2021 15:42:00 +0800 Subject: [PATCH 3/8] Add the function body to the getLPFee function Signed-off-by: cyl19970726 <15258378443@163.com> --- contracts/app/Bridge.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index dcdfbce..9f3170f 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -107,6 +107,7 @@ contract BridgeDestination { view returns (uint256) { + uint256 currentTime = block.timestamp; if (currentTime < startTime){ return 0; }else if(currentTime >= transferData.startTime + transferData.feeRampup){ From 140050d557f29e8135b85337587a378c0fc3dd13 Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Thu, 23 Dec 2021 15:52:48 +0800 Subject: [PATCH 4/8] modify the function body to the getLPFee function Signed-off-by: cyl19970726 <15258378443@163.com> --- contracts/app/Bridge.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index 9f3170f..a8b20fe 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -108,12 +108,12 @@ contract BridgeDestination { returns (uint256) { uint256 currentTime = block.timestamp; - if (currentTime < startTime){ + if (currentTime < transferData.startTime){ return 0; }else if(currentTime >= transferData.startTime + transferData.feeRampup){ return transferData.fee; }else{ - return transferData.fee * (transferData.currentTime - transferData.startTime); + return transferData.fee * (currentTime - transferData.startTime); } } From 68e75931dfbd37c65cdb7a5f142fe4a51665f3ea Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Thu, 23 Dec 2021 17:39:42 +0800 Subject: [PATCH 5/8] BridgeDestination.withdraw() will support native token transfer Signed-off-by: cyl19970726 <15258378443@163.com> --- contracts/app/Bridge.sol | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index a8b20fe..2a220d4 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -44,7 +44,7 @@ contract BridgeSource { if (sourceTokenAddress == address(0)){ require(msg.value >= amountPlusFee,"not enough msg.value"); - payable(sourceTokenAddress).transfer(amountPlusFee); + payable(address(this)).transfer(amountPlusFee); }else{ IERC20(sourceTokenAddress).safeTransferFrom( msg.sender, @@ -163,17 +163,27 @@ contract BridgeDestination { bytes32 key = keccak256(abi.encode(tkey)); require(ownerMap[key] != address(2**160 - 1), "already withdrawn"); - if (ownerMap[key] == address(0)) { - IERC20(tkey.transferData.tokenAddress).safeTransfer( - tkey.transferData.destination, - tkey.transferData.amount - ); - } else { - IERC20(tkey.transferData.tokenAddress).safeTransfer( - ownerMap[key], - tkey.transferData.amount - ); + + if (tkey.transferData.tokenAddress != address(0)){ + if (ownerMap[key] == address(0)) { + IERC20(tkey.transferData.tokenAddress).safeTransfer( + tkey.transferData.destination, + tkey.transferData.amount + ); + } else { + IERC20(tkey.transferData.tokenAddress).safeTransfer( + ownerMap[key], + tkey.transferData.amount + ); + } + }else{ + if (ownerMap[key] == address(0)) { + payable(tkey.transferData.destination).transfer(tkey.transferData.amount); + }else{ + payable(ownerMap[key]).transfer(tkey.transferData.amount); + } } + ownerMap[key] = address(2**160 - 1); // -1, not used any more } From 8abe7112738d17bc16392f2220fab22ccfe9d7fc Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Thu, 23 Dec 2021 20:52:55 +0800 Subject: [PATCH 6/8] format code Signed-off-by: cyl19970726 <15258378443@163.com> --- contracts/app/Bridge.sol | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index 2a220d4..a3cdfb8 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -37,15 +37,15 @@ contract BridgeSource { address sourceTokenAddress, BridgeLib.TransferData memory transferData, bytes32[] memory proof - ) public payable{ + ) public payable { // safemath not needed for solidity 8 uint256 amountPlusFee = (transferData.amount * (10000 + CONTRACT_FEE_BASIS_POINTS)) / 10000; - if (sourceTokenAddress == address(0)){ - require(msg.value >= amountPlusFee,"not enough msg.value"); + if (sourceTokenAddress == address(0)) { + require(msg.value >= amountPlusFee, "not enough msg.value"); payable(address(this)).transfer(amountPlusFee); - }else{ + } else { IERC20(sourceTokenAddress).safeTransferFrom( msg.sender, address(this), @@ -108,22 +108,24 @@ contract BridgeDestination { returns (uint256) { uint256 currentTime = block.timestamp; - if (currentTime < transferData.startTime){ + if (currentTime < transferData.startTime) { return 0; - }else if(currentTime >= transferData.startTime + transferData.feeRampup){ + } else if ( + currentTime >= transferData.startTime + transferData.feeRampup + ) { return transferData.fee; - }else{ - return transferData.fee * (currentTime - transferData.startTime); + } else { + return transferData.fee * (currentTime - transferData.startTime); } } - function buy(TransferKey memory tkey) public payable{ + function buy(TransferKey memory tkey) public payable { uint256 amount = tkey.transferData.amount - getLPFee(tkey.transferData); - - if(tkey.transferData.tokenAddress == address(0)){ - require(msg.value >= amount,"not enough msg.value"); + + if (tkey.transferData.tokenAddress == address(0)) { + require(msg.value >= amount, "not enough msg.value"); payable(tkey.transferData.destination).transfer(amount); - }else{ + } else { // TODO: another token address on dest. chain? IERC20(tkey.transferData.tokenAddress).safeTransferFrom( msg.sender, @@ -164,7 +166,7 @@ contract BridgeDestination { bytes32 key = keccak256(abi.encode(tkey)); require(ownerMap[key] != address(2**160 - 1), "already withdrawn"); - if (tkey.transferData.tokenAddress != address(0)){ + if (tkey.transferData.tokenAddress != address(0)) { if (ownerMap[key] == address(0)) { IERC20(tkey.transferData.tokenAddress).safeTransfer( tkey.transferData.destination, @@ -176,14 +178,15 @@ contract BridgeDestination { tkey.transferData.amount ); } - }else{ + } else { if (ownerMap[key] == address(0)) { - payable(tkey.transferData.destination).transfer(tkey.transferData.amount); - }else{ + payable(tkey.transferData.destination).transfer( + tkey.transferData.amount + ); + } else { payable(ownerMap[key]).transfer(tkey.transferData.amount); } } - ownerMap[key] = address(2**160 - 1); // -1, not used any more } From 1445451ed352291047b56ea958dddc20c1ae992e Mon Sep 17 00:00:00 2001 From: cyl19970726 <52317293+cyl19970726@users.noreply.github.com> Date: Fri, 24 Dec 2021 13:32:29 +0800 Subject: [PATCH 7/8] Update contracts/app/Bridge.sol modify BridgeDestination.getLPFee() Co-authored-by: Qi Zhou --- contracts/app/Bridge.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index a3cdfb8..31cf2dd 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -115,7 +115,7 @@ contract BridgeDestination { ) { return transferData.fee; } else { - return transferData.fee * (currentTime - transferData.startTime); + return transferData.fee * (currentTime - transferData.startTime) / transferData.feeRampup; } } From bff4d07e8e74cb428b155d0e68900a6d90a55698 Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Fri, 24 Dec 2021 14:05:34 +0800 Subject: [PATCH 8/8] update contracts/app/Bridge.sol add nonReentrant to BridgeDestination.withdraw() and BridgeDestination.buy() Signed-off-by: cyl19970726 <15258378443@163.com> --- contracts/app/Bridge.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/app/Bridge.sol b/contracts/app/Bridge.sol index 31cf2dd..31c8887 100644 --- a/contracts/app/Bridge.sol +++ b/contracts/app/Bridge.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "../DynamicMerkleTree.sol"; @@ -69,7 +70,7 @@ contract BridgeSource { } } -contract BridgeDestination { +contract BridgeDestination is ReentrancyGuard { using SafeERC20 for IERC20; struct TransferKey { @@ -115,11 +116,11 @@ contract BridgeDestination { ) { return transferData.fee; } else { - return transferData.fee * (currentTime - transferData.startTime) / transferData.feeRampup; + return transferData.fee * (currentTime - transferData.startTime); } } - function buy(TransferKey memory tkey) public payable { + function buy(TransferKey memory tkey) public payable nonReentrant { uint256 amount = tkey.transferData.amount - getLPFee(tkey.transferData); if (tkey.transferData.tokenAddress == address(0)) { @@ -146,7 +147,7 @@ contract BridgeDestination { address sourceContract, uint256 transferLen, bytes32[] memory recordProof - ) public { + ) public nonReentrant { if (!validatedStateRoots[stateRoot]) { // TODO: prove stateRoot is in stateRootProof validatedStateRoots[stateRoot] = true;