26017 - [SC - Insight] getTransactionCount will break at some point ru...

Submitted on Nov 23rd 2023 at 02:11:00 UTC by @dontonka for Boost | DeGate

Report ID: #26017

Report type: Smart Contract

Report severity: Insight

Target: https://etherscan.io/address/0x2028834B2c0A36A918c10937EeA71BE4f932da52#code

Impacts:

  • Unbounded gas consumption

Description

Bug Description

getTransactionCount vulnerable to run out of gas and DoS even if it's a view function. So whatever clients rely on this view function would not be able todo his job anymore as calling this function would always revert.

Impact

getTransactionCount will always revert once ~1300 transactions (in Remix the gas limit seems to be 3M) have been submitted throught the wallet. The gas limit seems to be 30M thought, I'm not sure why in Remix it revert at 3M, but if it needs to reach 30M, then the cap is around 12000 transactions (see PoC)

Recommendation

The problem is the for loop for (uint i=0; i<transactionCount; i++) which will iterate over all the txs submitted. Even if it's only to update a counter, it will exhaust all the gas available at some point, and this seems to be around having submitted 1300 transactions.

Similar to what getTransactionIds is doing, you would need to introduce a range of ids you want (uint from, uint to), and ensure the for loop is only considering this range.

Proof of concept

You will have to clone the immunefi poc repo and follow the steps below. I had to upgrade the MultiSigWallet code to match solc v0.8.19 compiler in order todo this PoC. Nevertheles, I also tested in Remix using the same compiler (v0.4.26, also using the original code) and the it start reverting at around 1300 txs. Once you run the test, you can see the gas used which is above 30M.

  • git clone https://github.com/immunefi-team/forge-poc-templates.git

  • forge init --template immunefi-team/forge-poc-templates --branch default

  • Add the following code in src folder, which is the MultiSigWallet.sol contract but upgraded to compile with Solc 0.8.19.

  • Replace test/PoCTest.sol with the following test.

  • forge test -vv --match-test testAttack

I've also tested it in Remix the following way:

  • Add the MultiSigWallet.sol to Remix

  • Add the following code at the end of the Constructor

  • Deploy with 2 valid owner and 2 required

  • Call getTransactionCount with true, true

  • Check the execution gas cost, it will be almost 3M, which is the limit.

  • Call submitTransaction about 150 times to reach 1250 (valid address, 0 and 0x00)

  • Call getTransactionCount with true, true

    • This will revert, running out of gas. While all those transaction are pending, even if you try to call it only looking for executed, it will still blow up or be very close to.

Last updated

Was this helpful?