Boost _ IDEX 34566 - [Smart Contract - Insight] Withdrawingsolwithdraw_delegatecall - Its possible f
Submitted on Thu Aug 15 2024 22:52:26 GMT-0400 (Atlantic Standard Time) by @OxSCSamurai for Boost | IDEX
Report ID: #34566
Report type: Smart Contract
Report severity: Insight
Target: https://github.com/idexio/idex-contracts-ikon/blob/main/contracts/libraries/Withdrawing.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
Summary:
The problem is that the current logic allows for users to withdraw an amount equal to the
maximumGasFee
, which will cause the user to receive nothing but still pay withdrawal transaction fees.There seems to be no checks to prevent this from happening.
The affected function:
https://github.com/idexio/idex-contracts-ikon/blob/4b4e154cb28269972c87f6c8864bf65cbea8220e/contracts/libraries/Withdrawing.sol#L98-L154
The affected require statement:
Impact Details
Impact:
Impact in scope:
Contract fails to deliver promised returns, but doesn't lose value
- low severity >>> Absolutely no user ever expects to receive zero amount when completing a withdrawal transaction successfully.Any user would expect to receive a withdrawn amount of > 0, therefore the contract fails to deliver on promised or expected returns or behaviour in terms of withdrawal functionality.
Impact Analysis:
Expected Returns:
Users generally expect that when they initiate a withdrawal, they will receive a certain value or asset in return for their transaction. In this case, if a user attempts to withdraw assets and receives zero value, the contract is failing to deliver the expected returns.
Additionally, the require statement's error/revert message states
Excessive withdrawal fee
, which is when withdrawal fee is greater than the withdraw amount. This means the user will NOT get > 0 out in withdrawal amounts, so that's why the require check is there to prevent zero amount withdrawals. But the require check unfortunately fails to prevent zero amount withdrawals for casearguments.withdrawal.maximumGasFee == arguments.withdrawal.grossQuantity
.So there's an inconsistency here: on one hand the require check is there to prevent a situation where a user withdraws and receives a zero amount of tokens, but the check fails to account for all possible cases where withdrawn amount will end up being zero.
User Experience:
The ability to withdraw zero value while still being charged fees can negatively impact the user experience. Users may feel that they are being penalized for attempting to withdraw their assets, even if the contract itself is not losing value.
Such scenarios can affect the trust and credibility of the protocol. Users may question the fairness of the fee structure and the overall design of the contract if they find themselves in situations where they incur costs without receiving any tangible benefits.
References
https://github.com/idexio/idex-contracts-ikon/blob/4b4e154cb28269972c87f6c8864bf65cbea8220e/contracts/libraries/Withdrawing.sol#L98-L154
Proof of concept
Proof of Concept
PoC Tests:
The existing hardhat/typescript test I used with slight modifications:
idex-contracts-ikon/test/withdrawals.ts
:
Test 1: Demonstrating that a user can receive zero amount after trying to withdraw > 0 amount, and still be charged fees:
Using:
Test 1 results:
The withdraw transaction was successful, and user has received zero withdrawal amount but was still charged fees...
Test 2: Demonstrating the bugfix, now the user shouldnt be able to receive zero withdrawal amount. The transaction should revert.
Yes, the user probably still pays miner/validator fees here(for reverted/failed txs) but this is expected.
But it's not expected to have a successful withdrawal transaction and receive zero withdrawal amount. Using:
Test 2 results:
The withdraw tx failed/reverted, as it should.
With the bugfix implemented the withdraw tx now reverts, preventing user from receiving zero withdraw amount.
Suggested bugfix:
To prevent users from withdrawing an amount that results in zero value after fees, ensure that the gross quantity is greater than the maximum gas fee while also verifying that the specified gas fee does not exceed the maximum allowable gas fee:
Last updated