i have the following:
contract Example {
function A() external {
(bool success,) = address(this).call{gas: 1_000_000}(abi.encodeWithSelector(this.B.selector));
console.log("A", success);
}
function B() external {
console.log("i have", gasleft());
(bool success,) = address(this).call{gas: 10_000_000}(abi.encodeWithSelector(this.useInfiniteGas.selector));
console.log("B", success);
console.log("ok", gasleft());
}
function useInfiniteGas() external view {
console.log("i am given", gasleft());
while (true) {}
}
}
after calling A(), i would expect A to be false and B to never print
but instead i get
i have 999817
i am given 980422
B false
ok 14714
A true
it seems like despite me setting 10M gas for B, it actually only got 980422, which has enough left to let A succeed. How does this work exactly?
same behavior occurs with delegatecall. if i set the 10M to anything above 980422 or remove it, same behavior. but if i set the 10M to anything below 980422, it now regains control of its gas limit.