Skip to content

Commit

Permalink
fix: capping gasLimit in the quoteEvmDeliveryPrice
Browse files Browse the repository at this point in the history
  • Loading branch information
liu-zhipeng committed Jul 6, 2023
1 parent ea8deeb commit 8bbd58f
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 14 deletions.
Expand Up @@ -50,7 +50,9 @@ abstract contract BaseWormhole is GasCap {
* https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/relayer/deliveryProvider/DeliveryProvider.sol
*/
function quoteEVMDeliveryPrice(uint256 _gasLimit, address _amb) public view returns (uint256 _cost) {
(_cost, ) = IWormholeRelayer(_amb).quoteEVMDeliveryPrice(MIRROR_WORMHOLE_ID, 0, _gasLimit);
// First Get the gas, if it is more than the cap use the cap
// And calculcate delievery price with gasCap
(_cost, ) = IWormholeRelayer(_amb).quoteEVMDeliveryPrice(MIRROR_WORMHOLE_ID, 0, _getGas(_gasLimit));
}

// ============ Private fns ============
Expand Down Expand Up @@ -105,8 +107,11 @@ abstract contract BaseWormhole is GasCap {
// Should always be sending a merkle root
require(_data.length == 32, "!data length");

// Should include gas limit info in specialized calldata
require(_encodedData.length == 32, "!encoded data length");

//calculate cost to deliver message
uint256 gasLimit = _getGasFromEncoded(_encodedData);
uint256 gasLimit = abi.decode(_encodedData, (uint256));
uint256 deliveryCost = quoteEVMDeliveryPrice(gasLimit, _amb);
require(deliveryCost == msg.value, "!msg.value");

Expand All @@ -129,15 +134,4 @@ abstract contract BaseWormhole is GasCap {
require(uint256(_whFormatAddress) >> 160 == 0, "!evm address");
return address(uint160(uint256(_whFormatAddress)));
}

/**
* @notice Using Wormhole relayer (AMB), the gas is provided to `sendMessage` as an encoded uint
*/
function _getGasFromEncoded(bytes memory _encodedData) internal view returns (uint256 _gas) {
// Should include gssas info in specialized calldata
require(_encodedData.length == 32, "!encoded data length");

// Get the gas, if it is more than the cap use the cap
_gas = _getGas(abi.decode(_encodedData, (uint256)));
}
}
Expand Up @@ -101,8 +101,69 @@ contract WormholeHubConnectorTest is ConnectorHelper {
WormholeHubConnector(_l1Connector).sendMessage{value: 100}(_data, encodedData);
}

function test_WormholeHubConnector_sendMessage_sendMessageWithGasCap(bytes memory _data) public {
vm.assume(_data.length == 32);

uint256 gasLimit = _gasCapL2 + 1;
bytes memory encodedData = abi.encode(gasLimit);

// Mock the call to fees
vm.mockCall(
_amb,
abi.encodeWithSignature("quoteEVMDeliveryPrice(uint16,uint256,uint256)", _chainIdL2, 0, _gasCapL2),
abi.encode(100, 100)
);

// Mock the call to sendPayloadToEvm
vm.mockCall(
_amb,
100,
abi.encodeWithSignature(
"sendPayloadToEvm(uint16,address,bytes,uint256,uint256,uint16,address)",
_chainIdL2,
address(_l2Connector),
_data,
uint256(0),
gasLimit,
_chainIdL2,
_owner
),
abi.encode(uint64(1))
);

// Check: correct event?
vm.expectEmit(false, false, false, true, _l1Connector);
emit MessageSent(_data, encodedData, _rootManager);

// Check: call to sendPayloadToEvm?
vm.expectCall(
_amb,
100,
abi.encodeWithSignature(
"sendPayloadToEvm(uint16,address,bytes,uint256,uint256,uint16,address)",
_chainIdL2,
address(_l2Connector),
_data,
0,
gasLimit,
_chainIdL2,
_owner
)
);

// Check: call to fees?
vm.expectCall(
_amb,
abi.encodeWithSignature("quoteEVMDeliveryPrice(uint16,uint256,uint256)", _chainIdL2, 0, _gasCapL2)
);

vm.deal(_rootManager, 1 ether);
vm.prank(_rootManager);
WormholeHubConnector(_l1Connector).sendMessage{value: 100}(_data, encodedData);
}

// Access control
function test_WormholeHubConnector_sendMessage_revertIfSenderIsNotRootManager(
function test_WormholeConnector_sendMessage_revertIfSenderIsNotRootManager(
address _nonRootManager,
bytes memory _data
) public {
Expand Down
Expand Up @@ -116,6 +116,65 @@ contract WormholeSpokeConnectorTest is ConnectorHelper {
WormholeSpokeConnector(_l2Connector).send{value: 100}(encodedData);
}

function test_WormholeSpokeConnector_send_sendWithGasCap(bytes32 _root) public {
vm.assume(_root != bytes32(0));
uint256 gasLimit = _gasCapL1 + 1;
bytes memory encodedData = abi.encode(gasLimit);
bytes memory _data = abi.encodePacked(_root);

// Mock the call to fees
vm.mockCall(
_amb,
abi.encodeWithSignature("quoteEVMDeliveryPrice(uint16,uint256,uint256)", _chainIdL1, 0, _gasCapL1),
abi.encode(100, 100)
);

vm.mockCall(_merkle, abi.encodeWithSelector(MerkleTreeManager.root.selector), abi.encode(_root));

// Mock the call to sendPayloadToEvm
vm.mockCall(
_amb,
100,
abi.encodeWithSignature(
"sendPayloadToEvm(uint16,address,bytes,uint256,uint256,uint16,address)",
_chainIdL1,
address(_l1Connector),
_data,
uint256(0),
gasLimit,
_chainIdL1,
_owner
),
abi.encode(uint64(1))
);

// Check: call to sendPayloadToEvm?
vm.expectCall(
_amb,
100,
abi.encodeWithSignature(
"sendPayloadToEvm(uint16,address,bytes,uint256,uint256,uint16,address)",
_chainIdL1,
address(_l1Connector),
_data,
0,
gasLimit,
_chainIdL1,
_owner
)
);

// Check: call to fees?
vm.expectCall(
_amb,
abi.encodeWithSignature("quoteEVMDeliveryPrice(uint16,uint256,uint256)", _chainIdL1, 0, _gasCapL1)
);

vm.deal(_owner, 1 ether);
vm.prank(_owner);
WormholeSpokeConnector(_l2Connector).send{value: 100}(encodedData);
}

// data length
function test_WormholeSpokeConnector_send_failsIfBadDataLength(bytes memory _data) public {
vm.assume(_data.length != 32);
Expand Down

0 comments on commit 8bbd58f

Please sign in to comment.