Open hats-bug-reporter[bot] opened 9 months ago
No attempt is made to use the return value from approve
.
@alex-sumner The token is wrapped in IERC20 interface. However if the token does not return a bool
value for the approve transaction, the entire transaction fails, because the IERC20 interface tries to return a bool
when the approve
call is made, but there is nothing to return so the call fails.
The current test is not catching it, because it is using the DummyToken
which is ERC20 compatible. The provided test uses directly USDT (a non-compatible ERC20 token) on a mainnet fork for simplicity. However this issue could arise with any non-ERC20 compatible token on any chain.
Are you sure you attached the correct BfxVault.t.sol ? The one above seems identical to the original.
@alex-sumner The token is wrapped in IERC20 interface. However if the token does not return a
bool
value for the approve transaction, the entire transaction fails, because the IERC20 interface tries to return abool
when theapprove
call is made, but there is nothing to return so the call fails.The current test is not catching it, because it is using the
DummyToken
which is ERC20 compatible. The provided test uses directly USDT (a non-compatible ERC20 token) on a mainnet fork for simplicity. However this issue could arise with any non-ERC20 compatible token on any chain.
Apologies, you are right. I reproduced it by making DummyToken non-compliant. I don't think it is medium however as it can only happen if the deployer, or subsequently the owner, uses a non-compliant token. So it falls under either a misconfigured deployment that will never work, or a malicious owner.
@alex-sumner Although I agree that it is related to misconfigured deployment or a malicious owner / mistake by owner, I think applying the suggested fix does not hurt as it is quite similar to the approach taken for transfer
and transferFrom
. Based on your input I would still consider it a Low
validity issue, tho I am not sure what base fee receiver labeled - low
means.
Yes I agree that switching to a low level call as is done for transfer makes sense. I have changed the labelling to indicate a valid report of a low level vulnerability, and I have removed the "won't fix" label.
Btw applying the fix will also help the owner not having to check each paymentToken
contract to see if it is ERC20 compliant :)
Github username: -- Twitter username: -- Submission hash (on-chain): 0x059169db82ba34561195e8796e8fded847e14db63af3ce3d094228c29329ad30 Severity: medium
Description: Description\ The protocol is intended to work with any ERC20 compatible tokens and even with some incompatible i.e. tokens that do not return a
bool
value when calling some of their functions such astransfer
ortransferFrom
directly. This is achieved by utilizing low-level calls within the transfer functions implemented in the protocol. However within theBfxVault.sol
contract we have themakeDeposit()
function that is callable only by users withTREASURER_ROLE
. This function calls an internal_doDeposit()
function which executes two steps:deposit()
function on the BFX contract which transfers the provided amount from the BfxVault contract.In order for the execution to happen properly the TRASURER has to transfer the specified amount before invoking the
makeDeposit()
function.The vulnerability here presents itself during the execution of
makeDeposit()
where a call is made topaymentToken.approve()
, wherepaymentToken
is wrapped with the IERC20 interface. However for tokens that do not return abool
value when calling approve such as USDT on Ethereum, the transaction will revert with an EVM error.I am considering this issue with Medium severity due to the possibility of the owner to retrieve those tokens by invoking
withdrawTokensTo()
.Attack Scenario\
If
paymentToken
is set to USDT or any other token that do not return abool
value whenapprove()
function is called, the TREASURER of the BfxVault will not be able to make a deposit from the vault to the Bfx Exchange due to failure in themakeDeposit()
function execution.Attachments
BfxVault.t.sol
is the PoC for the discovered issue. Steps to run it:test
folderETH_RPC_URL
forge test --match-contract BfxFail --fork-url $ETH_RPC_URL -vv
EvmError: Revert
message_makeApprove
internal function which utilizes low-level calls similar to_makeTransfer
and_makeTransferFrom
_makeApprove
call to set the approval to 0 in order to avoid future issues with tokens that require approval to 0 firstFiles: