Skip to content
This repository was archived by the owner on Apr 23, 2024. It is now read-only.

Commit 559b8a9

Browse files
committed
explicitly check amount of tokens deposited to bridge
1 parent 978ba8c commit 559b8a9

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

solidity/contracts/Bridge.sol

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
pragma solidity ^0.8.0;
44
import "./Auth.sol";
55
import "./StellarAsset.sol";
6+
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
67
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
78
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
9+
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
810

911
// Every bridge transfer has a globally unique id.
1012
//
@@ -80,7 +82,7 @@ bytes32 constant WITHDRAW_ETH_ID = keccak256("withdrawETH");
8082
// WITHDRAW_ERC20_ID is used to distinguish withdrawERC20() signatures from signatures for other bridge functions.
8183
bytes32 constant WITHDRAW_ERC20_ID = keccak256("withdrawERC20");
8284

83-
contract Bridge is Auth {
85+
contract Bridge is Auth, ReentrancyGuard {
8486
// paused is a bitmask which determines whether deposits / withdrawals are enabled on the bridge
8587
uint8 public paused;
8688
// SetPaused is emitted whenever the paused state of the bridge changes
@@ -134,7 +136,7 @@ contract Bridge is Auth {
134136
address token,
135137
uint256 destination,
136138
uint256 amount
137-
) external {
139+
) external nonReentrant {
138140
require((paused & PAUSE_DEPOSITS) == 0, "deposits are paused");
139141
require(amount > 0, "deposit amount is zero");
140142
require(token != address(0x0), "invalid token address");
@@ -145,12 +147,16 @@ contract Bridge is Auth {
145147
if (isStellarAsset[token]) {
146148
StellarAsset(token).burn(msg.sender, amount);
147149
} else {
150+
IERC20 tokenContract = IERC20(token);
151+
uint256 before = tokenContract.balanceOf(address(this));
148152
SafeERC20.safeTransferFrom(
149-
IERC20(token),
153+
tokenContract,
150154
msg.sender,
151155
address(this),
152156
amount
153157
);
158+
uint256 received = SafeMath.sub(tokenContract.balanceOf(address(this)), before);
159+
require(amount == received, "received amount not equal to expected amount");
154160
}
155161
}
156162

solidity/contracts/FeeToken.sol

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// contracts/Auth.sol
2+
// SPDX-License-Identifier: Apache-2.0
3+
pragma solidity ^0.8.0;
4+
import "./StellarAsset.sol";
5+
6+
7+
contract FeeToken is StellarAsset {
8+
9+
constructor(
10+
string memory name_,
11+
string memory symbol_,
12+
uint8 decimals_
13+
) StellarAsset(name_, symbol_, decimals_) {}
14+
15+
function transferFrom(
16+
address sender,
17+
address recipient,
18+
uint256 amount
19+
) public virtual override returns (bool) {
20+
return super.transferFrom(sender, recipient, amount-1);
21+
}
22+
}

solidity/test/erc20.js

+14
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,20 @@ describe("Deposit & Withdraw ERC20", function() {
5454
await setPaused(bridge, signers, domainSeparator, PAUSE_NOTHING, nextPauseNonce(), validTimestamp());
5555
});
5656

57+
it("block deposits for tokens which transfer less than expected amount", async function() {
58+
const FeeToken = await ethers.getContractFactory("FeeToken");
59+
const feeToken = await FeeToken.deploy("Fee Token", "FEE", 18);
60+
await feeToken.mint(sender.address, ethers.utils.parseEther("100.0"));
61+
await feeToken.approve(bridge.address, ethers.utils.parseEther("300.0"));
62+
63+
await setDepositAllowed(bridge, signers, domainSeparator, feeToken.address, true, 1, validTimestamp());
64+
expect(await bridge.depositAllowed(feeToken.address)).to.be.true;
65+
66+
await expect(bridge.depositERC20(
67+
feeToken.address, 1, ethers.utils.parseEther("1.0")
68+
)).to.be.revertedWith("received amount not equal to expected amount");
69+
});
70+
5771
it("block deposits for a specific ERC20 token", async function() {
5872
const blockedToken = await ERC20.deploy("Blocked Test Token", "BLOCKED", 18);
5973
await blockedToken.mint(sender.address, ethers.utils.parseEther("100.0"));

0 commit comments

Comments
 (0)