Open hats-bug-reporter[bot] opened 4 months ago
It's a duplicate of my submission #61.
It's a duplicate of my submission #61.
You did not provide any reason why this bug happened, where the bug is, how we can mitigate this. The issue is the same but this report is more detailed and perfectly points out how everything works.
It's a duplicate of my submission #61.
You did not provide any reason why this bug happened, where the bug is, how we can mitigate this. The issue is the same but this report is more detailed and perfectly points out how everything works.
It's a duplicate of my submission #61.
You did not provide any reason why this bug happened, where the bug is, how we can mitigate this. The issue is the same but this report is more detailed and perfectly points out how everything works.
- Okay, thanks for "your admission" that this issue is the "same". And btw, you just submitted a few hours after I submitted mine which made me doubt about your intentions (but never mind).
- There are multiple ways to mitigate, but I want to focus my report on pointing out the "vulnerability and attack" because that is the "number one" priority.
- Let's end it here, let's give the decision to the judge.
Actually brother I saved it 1 day ago, I was not aware about the rules of hatsfinance that only first submission will be accepted so i thought I will submit after finding some more issue, but yesterday I got to know that so submitted. No issue, let see what happened.
This is not a bug. The withdrawal will only succeed if the signature comes from the external_signer set on the contract (see the function verify
in EIP712Verifier.sol). The attacker has no way of obtaining such a signature.
Github username: @itsabinashb Twitter username: 0xAbinash Submission hash (on-chain): 0x41a9b01289482b0d0f0495957fa264feb619b613f4f94b20d82f11d81fb54728 Severity: high
Description: Description\ The
Bfx.sol::withdraw()
does not have any check for whether a caller, who wants to withdraw, is a valid caller or not. It does not even check whether the caller is depositor or not. As a result an attacker can call this function with a validdepositId
and drain all fund provided if the signer signs the transaction.Attack Scenario\ We can see that the
withdraw()
isexternal
function means anybody can call this function. The attack is so simple, we can visualize this like this:deposit()
, suppose hisdepositId
is 37000.withdraw()
with thatdepositId
.Attachments
import '../src/Bfx.sol'; import './DummyToken.sol'; import './utils/SigUtils.sol'; import 'forge-std/Test.sol'; import 'forge-std/console.sol'; import 'openzeppelin/utils/cryptography/EIP712.sol';
contract NewTest is Test, EIP712('', '') { address owner = vm.addr(10); address signer = vm.addr(1); address user = vm.addr(2); address attacker = vm.addr(3); Bfx bfx; DummyToken token; SigUtils sigUtils;
function setUp() public { token = new DummyToken(); bfx = new Bfx(owner, signer, address(token)); deal(address(token), user, 100); vm.prank(user); token.approve(address(bfx), 100);
}
function test_another() public { vm.prank(user); bfx.deposit(50);
} }
vm.prank(user); bfx.deposit(50);
Revised Code File (Optional) Here is the
withdraw()
:Put a check that restricts all caller except the
trader
to call this function. Also put a check to see whether the trader is depositor or not. While depositing the depositor's address can be added to a mapping.