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

Improve MultiMessageSender #76

Merged
merged 2 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
321 changes: 200 additions & 121 deletions src/MultiBridgeMessageSender.sol

Large diffs are not rendered by default.

11 changes: 0 additions & 11 deletions src/adapters/axelar/AxelarSenderAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,6 @@ contract AxelarSenderAdapter is BaseSenderAdapter {
}
}

/*/////////////////////////////////////////////////////////////////
EXTERNAL VIEW FUNCTIONS
////////////////////////////////////////////////////////////////*/

/// @inheritdoc IMessageSenderAdapter
function getMessageFee(uint256, address, bytes calldata) external view override returns (uint256) {
/// FIXME: axelar has no on-chain message fee estimate. should have to overpay and get refund
return 1 ether;
// return axelarChainRegistry.getFee(_toChainId, uint32(gac.getGlobalMsgDeliveryGasLimit()));
}

/*/////////////////////////////////////////////////////////////////
HELPER FUNCTIONS
////////////////////////////////////////////////////////////////*/
Expand Down
10 changes: 0 additions & 10 deletions src/adapters/wormhole/WormholeSenderAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,4 @@ contract WormholeSenderAdapter is BaseSenderAdapter {
}
}
}

/*/////////////////////////////////////////////////////////////////
EXTERNAL VIEW FUNCTIONS
////////////////////////////////////////////////////////////////*/

/// @inheritdoc IMessageSenderAdapter
function getMessageFee(uint256 _toChainId, address, bytes calldata) external view override returns (uint256 fee) {
/// note: 50000 GAS is commonly used across the MMA; move to some global contract
(fee,) = relayer.quoteEVMDeliveryPrice(chainIdMap[_toChainId], 0, senderGAC.getGlobalMsgDeliveryGasLimit());
}
}
6 changes: 0 additions & 6 deletions src/interfaces/adapters/IMessageSenderAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ interface IMessageSenderAdapter is SingleMessageDispatcher {
/// @notice returns name of the message bridge wrapped by the adapter
function name() external view returns (string memory);

/// @notice return the fee (in native token wei) that would be charged by the bridge for the provided remote call
/// @param _toChainId is the destination chain id
/// @param _to is the destination address on the destination chain
/// @param _data is the data to be sent to the destination chain
function getMessageFee(uint256 _toChainId, address _to, bytes calldata _data) external view returns (uint256);

/// @notice returns the bridge receiver adapter address for a given destination chain id
/// @param _chainId is the destination chain whose receiver adapter address is to be returned
function getReceiverAdapter(uint256 _chainId) external view returns (address);
Expand Down
9 changes: 9 additions & 0 deletions src/libraries/Error.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ library Error {
/// @dev is thrown if sender adapter array has duplicates
error DUPLICATE_SENDER_ADAPTER();

/// @dev is thrown if the sender adapter does not exist
error SENDER_ADAPTER_NOT_EXIST();

/// @dev is thrown if sender adapter array is not in ascending order or has duplicates
error INVALID_SENDER_ADAPTER_ORDER();

/// @dev is thrown if deadline is lapsed
error MSG_EXECUTION_PASSED_DEADLINE();

Expand Down Expand Up @@ -72,6 +78,9 @@ library Error {
/// @dev is thrown if sender adapter is not allowed on receiver adapter
error INVALID_SENDER_ADAPTER();

/// @dev is thrown if the sender adapter fee array is invalid
error INVALID_SENDER_ADAPTER_FEES();

/// @dev is thrown if final destination is not mma receiver on receiver adapter
error INVALID_FINAL_DESTINATION();

Expand Down
4 changes: 0 additions & 4 deletions test/contracts-mock/FailingSenderAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,4 @@ contract FailingSenderAdapter {
function dispatchMessage(uint256, address, bytes calldata) external payable returns (bytes32) {
revert();
}

function getMessageFee(uint256, address, bytes calldata) external pure returns (uint256) {
return 0;
}
}
9 changes: 8 additions & 1 deletion test/integration-tests/GracePeriodExpiry.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.9;

/// library imports
import {Vm} from "forge-std/Test.sol";
import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol";

/// local imports
import "test/Setup.t.sol";
Expand Down Expand Up @@ -31,13 +32,19 @@ contract GracePeriodExpiryTest is Setup {

/// send cross-chain message using MMA infra
vm.recordLogs();
uint256[] memory fees = new uint256[](2);
(uint256 wormholeFee,) =
IWormholeRelayer(POLYGON_RELAYER).quoteEVMDeliveryPrice(_wormholeChainId(DST_CHAIN_ID), 0, 0);
fees[0] = wormholeFee;
fees[1] = 0.01 ether;
MultiBridgeMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}(
DST_CHAIN_ID,
address(target),
abi.encode(MockUniswapReceiver.setValue.selector, ""),
0,
EXPIRATION_CONSTANT,
refundAddress
refundAddress,
fees
);

Vm.Log[] memory logs = vm.getRecordedLogs();
Expand Down
9 changes: 8 additions & 1 deletion test/integration-tests/MultiMessageAggregation.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.9;

/// library imports
import {Vm} from "forge-std/Test.sol";
import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol";

/// local imports
import "test/Setup.t.sol";
Expand Down Expand Up @@ -31,13 +32,19 @@ contract MultiBridgeMessageAggregationTest is Setup {

/// send cross-chain message using MMA infra
vm.recordLogs();
uint256[] memory fees = new uint256[](2);
(uint256 wormholeFee,) =
IWormholeRelayer(POLYGON_RELAYER).quoteEVMDeliveryPrice(_wormholeChainId(DST_CHAIN_ID), 0, 0);
fees[0] = wormholeFee;
fees[1] = 0.01 ether;
MultiBridgeMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}(
DST_CHAIN_ID,
address(target),
abi.encode(MockUniswapReceiver.setValue.selector, ""),
0,
EXPIRATION_CONSTANT,
refundAddress
refundAddress,
fees
);

Vm.Log[] memory logs = vm.getRecordedLogs();
Expand Down
9 changes: 8 additions & 1 deletion test/integration-tests/RemoteAdapterAdd.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.9;

/// library imports
import {Vm} from "forge-std/Test.sol";
import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol";

/// local imports
import "test/Setup.t.sol";
Expand Down Expand Up @@ -56,13 +57,19 @@ contract RemoteAdapterAdd is Setup {

/// send cross-chain message using MMA infra
vm.recordLogs();
uint256[] memory fees = new uint256[](2);
(uint256 wormholeFee,) =
IWormholeRelayer(POLYGON_RELAYER).quoteEVMDeliveryPrice(_wormholeChainId(DST_CHAIN_ID), 0, 0);
fees[0] = wormholeFee;
fees[1] = 0.01 ether;
MultiBridgeMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}(
DST_CHAIN_ID,
address(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]),
abi.encodeWithSelector(MultiBridgeMessageReceiver.updateReceiverAdapters.selector, adaptersToAdd, operation),
0,
EXPIRATION_CONSTANT,
refundAddress
refundAddress,
fees
);

Vm.Log[] memory logs = vm.getRecordedLogs();
Expand Down
9 changes: 8 additions & 1 deletion test/integration-tests/RemoteAdapterRemove.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.9;

/// library imports
import {Vm} from "forge-std/Test.sol";
import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol";

/// local imports
import "test/Setup.t.sol";
Expand Down Expand Up @@ -61,6 +62,11 @@ contract RemoteAdapterRemove is Setup {

/// send cross-chain message using MMA infra
vm.recordLogs();
uint256[] memory fees = new uint256[](2);
(uint256 wormholeFee,) =
IWormholeRelayer(POLYGON_RELAYER).quoteEVMDeliveryPrice(_wormholeChainId(DST_CHAIN_ID), 0, 0);
fees[0] = wormholeFee;
fees[1] = 0.01 ether;
MultiBridgeMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}(
DST_CHAIN_ID,
address(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]),
Expand All @@ -72,7 +78,8 @@ contract RemoteAdapterRemove is Setup {
),
0,
EXPIRATION_CONSTANT,
refundAddress
refundAddress,
fees
);

Vm.Log[] memory logs = vm.getRecordedLogs();
Expand Down
9 changes: 8 additions & 1 deletion test/integration-tests/RemoteSetQuorum.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.9;

/// library imports
import {Vm} from "forge-std/Test.sol";
import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol";

/// local imports
import "test/Setup.t.sol";
Expand All @@ -28,13 +29,19 @@ contract RemoteQuorumUpdate is Setup {

/// send cross-chain message using MMA infra
vm.recordLogs();
uint256[] memory fees = new uint256[](2);
(uint256 wormholeFee,) =
IWormholeRelayer(POLYGON_RELAYER).quoteEVMDeliveryPrice(_wormholeChainId(DST_CHAIN_ID), 0, 0);
fees[0] = wormholeFee;
fees[1] = 0.01 ether;
MultiBridgeMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}(
DST_CHAIN_ID,
address(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]),
abi.encodeWithSelector(MultiBridgeMessageReceiver.updateQuorum.selector, newQuorum),
0,
EXPIRATION_CONSTANT,
refundAddress
refundAddress,
fees
);

Vm.Log[] memory logs = vm.getRecordedLogs();
Expand Down
9 changes: 8 additions & 1 deletion test/integration-tests/RemoteTimelockUpdate.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.9;

/// library imports
import {Vm} from "forge-std/Test.sol";
import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol";

/// local imports
import "test/Setup.t.sol";
Expand All @@ -28,13 +29,19 @@ contract RemoteTimelockUpdate is Setup {

/// send cross-chain message using MMA infra
vm.recordLogs();
uint256[] memory fees = new uint256[](2);
(uint256 wormholeFee,) =
IWormholeRelayer(POLYGON_RELAYER).quoteEVMDeliveryPrice(_wormholeChainId(DST_CHAIN_ID), 0, 0);
fees[0] = wormholeFee;
fees[1] = 0.01 ether;
MultiBridgeMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}(
POLYGON_CHAIN_ID,
address(contractAddress[POLYGON_CHAIN_ID][bytes("TIMELOCK")]),
abi.encodeWithSelector(GovernanceTimelock.setDelay.selector, newDelay),
0,
EXPIRATION_CONSTANT,
refundAddress
refundAddress,
fees
);

Vm.Log[] memory logs = vm.getRecordedLogs();
Expand Down
9 changes: 8 additions & 1 deletion test/integration-tests/TimelockCheck.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.9;

/// library imports
import {Vm} from "forge-std/Test.sol";
import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol";

/// local imports
import "test/Setup.t.sol";
Expand Down Expand Up @@ -33,13 +34,19 @@ contract TimelockCheckTest is Setup {

/// send cross-chain message using MMA infra
vm.recordLogs();
uint256[] memory fees = new uint256[](2);
(uint256 wormholeFee,) =
IWormholeRelayer(POLYGON_RELAYER).quoteEVMDeliveryPrice(_wormholeChainId(DST_CHAIN_ID), 0, 0);
fees[0] = wormholeFee;
fees[1] = 0.01 ether;
MultiBridgeMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}(
DST_CHAIN_ID,
address(target),
abi.encode(MockUniswapReceiver.setValue.selector, ""),
0,
EXPIRATION_CONSTANT,
refundAddress
refundAddress,
fees
);

Vm.Log[] memory logs = vm.getRecordedLogs();
Expand Down
10 changes: 5 additions & 5 deletions test/unit-tests/MultiBridgeMessageReceiver.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ contract MultiBridgeMessageReceiverTest is Setup {
);

MultiBridgeMessageReceiver receiver;
address wormholeAdapterAddr;
address axelarAdapterAddr;
address wormholeAdapterAddr;
address timelockAddr;

/// @dev initializes the setup
Expand All @@ -32,16 +32,16 @@ contract MultiBridgeMessageReceiverTest is Setup {

vm.selectFork(fork[DST_CHAIN_ID]);
receiver = MultiBridgeMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]);
wormholeAdapterAddr = contractAddress[DST_CHAIN_ID]["WORMHOLE_RECEIVER_ADAPTER"];
axelarAdapterAddr = contractAddress[DST_CHAIN_ID]["AXELAR_RECEIVER_ADAPTER"];
wormholeAdapterAddr = contractAddress[DST_CHAIN_ID]["WORMHOLE_RECEIVER_ADAPTER"];
timelockAddr = contractAddress[DST_CHAIN_ID]["TIMELOCK"];
}

/// @dev initializer
function test_initialize() public {
address[] memory adapters = new address[](2);
adapters[0] = wormholeAdapterAddr;
adapters[1] = axelarAdapterAddr;
adapters[0] = axelarAdapterAddr;
adapters[1] = wormholeAdapterAddr;

bool[] memory operation = new bool[](2);
operation[0] = true;
Expand All @@ -51,8 +51,8 @@ contract MultiBridgeMessageReceiverTest is Setup {
dummyReceiver.initialize(ETHEREUM_CHAIN_ID, adapters, operation, 2, timelockAddr);

assertEq(dummyReceiver.quorum(), 2);
assertTrue(dummyReceiver.isTrustedExecutor(wormholeAdapterAddr));
assertTrue(dummyReceiver.isTrustedExecutor(axelarAdapterAddr));
assertTrue(dummyReceiver.isTrustedExecutor(wormholeAdapterAddr));
}

/// @dev initializer cannot be called twice
Expand Down
Loading
Loading