Oxhunter526
medium
The D3Trading
contract contains a vulnerability that results in an inaccurate balance check within the buyToken
function. This issue can lead to incorrect checks for the available balance of the fromToken
in the contract, potentially allowing transfers that exceed the actual token balance.
The buyToken
function performs a balance check using the expression IERC20(fromToken).balanceOf(address(this)) - state.balances[fromToken] >= payFromAmount
. However, this approach fails to account for tokens that have already been transferred out of the contract but have not been properly updated in the state.balances
mapping.
- Loss of funds: Due to the inaccurate balance check, the contract may allow token transfers even when the available balance is insufficient. This can result in the loss of funds as users mistakenly believe they have sufficient tokens in the contract.
- Incorrect token purchases: Users relying on the balance check to determine the availability of tokens may end up purchasing tokens that the contract does not have enough balance to fulfill. This can lead to failed transactions and a loss of trust in the contract's functionality.
- Prepare the environment:
- Deploy the vulnerable
D3rading
contract on a testnet or local blockchain network. - Set up accounts for the contract owner, user A, and user B.
- User A holds a significant amount of the
fromToken
in their account.
- Exploiting the balance check vulnerability:
- User A initiates a transaction to buy a large amount of
toToken
from the contract using thebuyToken
function. - User A sets a
maxPayAmount
that is equal to or slightly higher than the actual available balance offromToken
in the contract. - Due to the balance check vulnerability, the contract incorrectly considers the stored balance of
fromToken
as the available balance and approves the transaction. - The contract transfers the requested toToken to User A, depleting the stored balance of
toToken
in the contract.
- Subsequent transaction failure:
- User B attempts to sell their
fromToken
to the contract using thesellToken
function. - User B sets a
fromAmount
based on their availablefromToken
balance. - However, the contract fails to execute the transaction since the actual available balance of fromToken is lower than the specified
fromAmount
. - User B's transaction fails, causing frustration and potential financial loss.
This PoC demonstrates how the inaccurate balance check can lead to successful purchases without considering the actual available balance of
fromToken
in the contract. It also highlights the subsequent failure of transactions when users rely on the balance check to determine the available token balance.
Manual Review
- Implement an accurate balance tracking mechanism:
- Modify the contract to keep track of the total tokens transferred out of the contract and deduct them from the stored balance of
fromToken
. This ensures that the stored balance accurately reflects the actual available balance offromToken
in the contract.
- Enhance the balance check in the buyToken function:
- Instead of comparing the stored balance of
fromToken
with thepayFromAmount
, compare the actual available balance (considering tokens transferred out) with thepayFromAmount
.