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

fix(protocol): check 63/64 gasleft() not smaller than specified gaslimit #16613

Merged
merged 16 commits into from
Apr 4, 2024
23 changes: 20 additions & 3 deletions packages/protocol/contracts/bridge/Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ contract Bridge is EssentialContract, IBridge {
error B_MESSAGE_NOT_SUSPENDED();
error B_MESSAGE_SUSPENDED();
error B_NON_RETRIABLE();
error B_NOT_ENOUGH_GASLEFT();
error B_NOT_FAILED();
error B_NOT_RECEIVED();
error B_PERMISSION_DENIED();
Expand Down Expand Up @@ -284,9 +285,25 @@ contract Bridge is EssentialContract, IBridge {
refundAmount = _message.value;
_updateMessageStatus(msgHash, Status.DONE);
} else {
// Use the remaining gas if called by a the destOwner, else
// use the specified gas limit.
uint256 gasLimit = msg.sender == _message.destOwner ? gasleft() : _message.gasLimit;
uint256 gasLimit;
if (msg.sender == _message.destOwner) {
// Use the remaining gas if called by a the destOwner, else
// use the specified gas limit.
gasLimit = gasleft();
} else {
// The "1/64th rule" refers to the gasleft at the time the call is made. When a
// contract makes a call to another contract, it can only forward 63/64 of the
// gas remaining (gasleft) at that moment, ensuring that there is always some
// gas reserved for the calling contract to complete its execution after the
// called contract finishes. This does not necessarily relate to the gas amount
// specified in the call itself, but rather to the actual remaining gas at the
// time of the call.
//
// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md
if (_message.gasLimit > (gasleft() * 63) >> 6) revert B_NOT_ENOUGH_GASLEFT();

gasLimit = _message.gasLimit;
}

if (_invokeMessageCall(_message, msgHash, gasLimit)) {
_updateMessageStatus(msgHash, Status.DONE);
Expand Down
Loading