Skip to content

Commit

Permalink
add reantrancy test
Browse files Browse the repository at this point in the history
  • Loading branch information
alistair-singh committed Dec 24, 2024
1 parent 94a9f2e commit 41f01ba
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
26 changes: 26 additions & 0 deletions contracts/test/Gateway.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {IUpgradable} from "../src/interfaces/IUpgradable.sol";
import {Gateway} from "../src/Gateway.sol";
import {MockGateway} from "./mocks/MockGateway.sol";
import {MockGatewayV2} from "./mocks/MockGatewayV2.sol";
import {ReantrantAttacker} from "./mocks/ReantrantAttacker.sol";
import {GatewayProxy} from "../src/GatewayProxy.sol";

import {AgentExecutor} from "../src/AgentExecutor.sol";
Expand Down Expand Up @@ -1022,4 +1023,29 @@ contract GatewayTest is Test {
vm.expectRevert(Assets.TokenAlreadyRegistered.selector);
IGateway(address(gateway)).registerToken{value: fee}(dotToken);
}

function testReantrancyGuardReverts() public {
testRegisterToken();

ReantrantAttacker attacker = new ReantrantAttacker(address(gateway), address(token));
// Fund attacker
deal(address(attacker), 1 ether);
deal(address(token), address(attacker), 1);

uint128 amount = 1;
uint128 extra = 1;
uint128 destinationFee = 1;
ParaID paraID = ParaID.wrap(1000);

uint128 fee = uint128(IGateway(address(gateway)).quoteSendTokenFee(address(token), paraID, 0));

hoax(address(attacker));
token.approve(address(gateway), 1);

vm.expectRevert(NativeTransferFailed.selector);
hoax(address(attacker));
IGateway(address(gateway)).sendToken{value: fee + extra}(
address(token), paraID, recipientAddress32, destinationFee, amount
);
}
}
39 changes: 39 additions & 0 deletions contracts/test/mocks/ReantrantAttacker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.28;

import {IGateway} from "../../src/interfaces/IGateway.sol";
import {ParaID, MultiAddress, multiAddressFromBytes32} from "../../src/Types.sol";
import {console} from "forge-std/console.sol";

contract ReantrantAttacker {
address public owner;
IGateway targetContract;
uint256 targetValue = 0.9 ether;
uint256 fee;
ParaID assetHub = ParaID.wrap(1000);
uint128 amount = 1;
uint128 extra = 1;
MultiAddress recipientAddress32 = multiAddressFromBytes32(keccak256("recipient"));

constructor(address _targetAddr, address token) {
targetContract = IGateway(_targetAddr);
owner = msg.sender;
fee = targetContract.quoteSendTokenFee(token, assetHub, 0);
}

function balance() public view returns (uint256) {
return address(this).balance;
}

function withdrawAll() public returns (bool) {
require(msg.sender == owner, "my money!!");
uint256 totalBalance = address(this).balance;
(bool sent,) = msg.sender.call{value: totalBalance}("");
require(sent, "Failed to send Ether");
return sent;
}

receive() external payable {
targetContract.sendToken{value: amount + fee + extra}(address(0), assetHub, recipientAddress32, 1, amount);
}
}

0 comments on commit 41f01ba

Please sign in to comment.