Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nmirchev8_ctf Incorrect gas computation #46

Open
Divyanshu-Madhav opened this issue Aug 14, 2024 · 1 comment
Open

nmirchev8_ctf Incorrect gas computation #46

Divyanshu-Madhav opened this issue Aug 14, 2024 · 1 comment
Labels
invalid This doesn't seem right

Comments

@Divyanshu-Madhav
Copy link

Vulnerability

The vulnerability lies in the gas calculation logic within the _callWithExactGasSafeReturnData function. Specifically, the variable g is assigned the current gas value before the gas check:

let g := gas()

The subsequent check:

if lt(g, gasForCallExactCheck) {
    mstore(0x0, NO_GAS_FOR_CALL_EXACT_CHECK_SIG)
    revert(0x0, 0x4)
}

is performed without updating g to account for the gas used during this check. After this, the new gas value is calculated:

g := sub(g, gasForCallExactCheck)

However, this calculation does not account for the gas used during the previous check, leading to an overestimated value of g. As a result, when performing the final gas comparison:

if iszero(gt(sub(g, div(g, 64)), gasLimit)) {
    mstore(0x0, NOT_ENOUGH_GAS_FOR_CALL_SIG)
    revert(0x0, 0x4)
}

the comparison might falsely pass, leading to a scenario where the contract attempts to call the target with less gas than intended.

Impact

The impact of this vulnerability is that the contract may behave non-deterministically. Specifically, when the gas passed by the caller is strictly controlled, the contract might fail to revert as expected and proceed with the call, but with insufficient gas. This could lead to failed operations within the target contract, which contradicts the intended functionality of this contract . The call to the target contract may revert due to insufficient gas .

Solution

One way is to guess the gas that will be used for the check on the basis of the memory size and the dynamic behaviour of lt opcode.

@NicolaMirchev
Copy link
Contributor

This is not a problem, because gasForCallExactCheck is configured to be enough for both:

if lt(g, gasForCallExactCheck) 

and

if iszero(gt(sub(g, div(g, 64)), gasLimit)) {
    mstore(0x0, NOT_ENOUGH_GAS_FOR_CALL_SIG)
    revert(0x0, 0x4)
}

checks.

@NicolaMirchev NicolaMirchev added the invalid This doesn't seem right label Aug 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

2 participants