Skip to content

Commit

Permalink
fix: added unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sendra committed Dec 10, 2024
1 parent ef0978b commit a8acb23
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 15 deletions.
2 changes: 1 addition & 1 deletion scripts/Adapters/DeployLineaAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ abstract contract BaseDeployLineaAdapter is BaseAdapterScript {
LineaAdapterDeploymentHelper.getAdapterCode(
LineaAdapterDeploymentHelper.LineaAdapterArgs({
baseArgs: baseArgs,
inbox: LINEA_MESSAGE_SERVICE()
lineaMessageService: LINEA_MESSAGE_SERVICE()
})
);
}
Expand Down
10 changes: 1 addition & 9 deletions scripts/contract_extensions/LineaAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,7 @@ contract LineaAdapterTestnet is LineaAdapter {
address lineaMessageService,
uint256 providerGasLimit,
TrustedRemotesConfig[] memory trustedRemotes
)
LineaAdapter(
crossChainController,
lineaMessageService,
providerGasLimit,
trustedRemotes,
'Linea native adapter'
)
{}
) LineaAdapter(crossChainController, lineaMessageService, providerGasLimit, trustedRemotes) {}

/// @inheritdoc ILineaAdapter
function isDestinationChainIdSupported(uint256 chainId) public pure override returns (bool) {
Expand Down
9 changes: 4 additions & 5 deletions src/contracts/adapters/linea/LineaAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,22 @@ contract LineaAdapter is ILineaAdapter, BaseAdapter {
* @param crossChainController address of the cross chain controller that will use this bridge adapter
* @param lineaMessageService Linea entry point address
* @param providerGasLimit base gas limit used by the bridge adapter
* @param adapterName string indicating the adapter name
* @param trustedRemotes list of remote configurations to set as trusted
*/
constructor(
address crossChainController,
address lineaMessageService,
uint256 providerGasLimit,
string memory adapterName,
TrustedRemotesConfig[] memory trustedRemotes
) BaseAdapter(crossChainController, providerGasLimit, adapterName, trustedRemotes) {
) BaseAdapter(crossChainController, providerGasLimit, 'Linea native adapter', trustedRemotes) {
require(lineaMessageService != address(0), Errors.LINEA_MESSAGE_SERVICE_CANT_BE_ADDRESS_0);
LINEA_MESSAGE_SERVICE = lineaMessageService;
}

/// @inheritdoc IBaseAdapter
function forwardMessage(
address receiver,
uint256 executionGasLimit,
uint256,
uint256 destinationChainId,
bytes calldata message
) external virtual returns (address, uint256) {
Expand All @@ -69,7 +68,7 @@ contract LineaAdapter is ILineaAdapter, BaseAdapter {
}

/// @inheritdoc ILineaAdapter
function ovmReceive(bytes calldata message) external onlyLineaMessageService {
function receiveMessage(bytes calldata message) external onlyLineaMessageService {
uint256 originChainId = getOriginChainId();
address srcAddress = IMessageService(LINEA_MESSAGE_SERVICE).sender();
require(
Expand Down
1 change: 1 addition & 0 deletions src/contracts/libs/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ library Errors {
string public constant ZK_SYNC_BRIDGE_HUB_CANT_BE_ADDRESS_0 = '43'; // ZkSync Bridgehub can not be address 0
string public constant CL_GAS_PRICE_ORACLE_CANT_BE_ADDRESS_0 = '44'; // ChainLink gas price oracle can not be address 0
string public constant CALLER_NOT_LINEA_MESSAGE_SERVICE = '45'; // caller must be the Linea message service
string public constant LINEA_MESSAGE_SERVICE_CANT_BE_ADDRESS_0 = '46'; // Linea message service can not be address 0
}
275 changes: 275 additions & 0 deletions tests/adapters/LineaAdapter.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import {LineaAdapter, IBaseAdapter, ILineaAdapter, IMessageService} from '../../src/contracts/adapters/linea/LineaAdapter.sol';
import {ICrossChainReceiver} from '../../src/contracts/interfaces/ICrossChainReceiver.sol';
import {ChainIds} from 'solidity-utils/contracts/utils/ChainHelpers.sol';
import {Errors} from '../../src/contracts/libs/Errors.sol';
import {BaseAdapterTest} from './BaseAdapterTest.sol';

contract LineaAdapterTest is BaseAdapterTest {
LineaAdapter internal lineaAdapter;
event SetTrustedRemote(uint256 indexed originChainId, address indexed originForwarder);

modifier setLineaAdapter(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId
) {
vm.assume(crossChainController != tx.origin); // zkVM doesn't support mocking tx.origin
vm.assume(baseGasLimit < 1 ether);
_assumeSafeAddress(crossChainController);
_assumeSafeAddress(lineaMessageService);
vm.assume(originForwarder != address(0));
vm.assume(originChainId > 0);

IBaseAdapter.TrustedRemotesConfig memory originConfig = IBaseAdapter.TrustedRemotesConfig({
originForwarder: originForwarder,
originChainId: originChainId
});
IBaseAdapter.TrustedRemotesConfig[]
memory originConfigs = new IBaseAdapter.TrustedRemotesConfig[](1);
originConfigs[0] = originConfig;

lineaAdapter = new LineaAdapter(
crossChainController,
lineaMessageService,
baseGasLimit,
originConfigs
);
_;
}

struct Params {
address lineaMessageService;
address receiver;
uint256 dstGasLimit;
address caller;
}

function setUp() public {}

function testWrongLineaMessageSender(
address crossChainController,
uint256 baseGasLimit,
address originForwarder,
uint256 originChainId
) public {
vm.assume(crossChainController != address(0));
vm.assume(originForwarder != address(0));
vm.assume(originChainId > 0);

IBaseAdapter.TrustedRemotesConfig memory originConfig = IBaseAdapter.TrustedRemotesConfig({
originForwarder: originForwarder,
originChainId: originChainId
});
IBaseAdapter.TrustedRemotesConfig[]
memory originConfigs = new IBaseAdapter.TrustedRemotesConfig[](1);
originConfigs[0] = originConfig;
vm.expectRevert(bytes(Errors.LINEA_MESSAGE_SERVICE_CANT_BE_ADDRESS_0));
new LineaAdapter(crossChainController, address(0), baseGasLimit, originConfigs);
}

function testInitialize(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId
)
public
setLineaAdapter(
crossChainController,
lineaMessageService,
originForwarder,
baseGasLimit,
originChainId
)
{
assertEq(lineaAdapter.getTrustedRemoteByChainId(originChainId), originForwarder);
}

function testForwardMessage(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId
)
public
setLineaAdapter(
crossChainController,
lineaMessageService,
originForwarder,
baseGasLimit,
originChainId
)
{
_testForwardMessage(
Params({
lineaMessageService: lineaMessageService,
receiver: address(135961),
dstGasLimit: 12,
caller: address(12354)
})
);
}

function testForwardMessageWhenChainNotSupported(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId,
uint256 dstGasLimit,
address receiver,
bytes memory message
)
public
setLineaAdapter(
crossChainController,
lineaMessageService,
originForwarder,
baseGasLimit,
originChainId
)
{
vm.assume(receiver != address(0));

vm.expectRevert(bytes(Errors.DESTINATION_CHAIN_ID_NOT_SUPPORTED));
lineaAdapter.forwardMessage(receiver, dstGasLimit, 11, message);
}

function testForwardMessageWhenWrongReceiver(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId,
uint256 dstGasLimit,
bytes memory message
)
public
setLineaAdapter(
crossChainController,
lineaMessageService,
originForwarder,
baseGasLimit,
originChainId
)
{
vm.expectRevert(bytes(Errors.RECEIVER_NOT_SET));
lineaAdapter.forwardMessage(address(0), dstGasLimit, ChainIds.LINEA, message);
}

function testReceive(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
bytes memory message
)
public
setLineaAdapter(crossChainController, lineaMessageService, originForwarder, baseGasLimit, 1)
{
hoax(lineaMessageService);

vm.mockCall(
lineaMessageService,
abi.encodeWithSelector(IMessageService.sender.selector),
abi.encode(originForwarder)
);
vm.mockCall(
crossChainController,
abi.encodeWithSelector(ICrossChainReceiver.receiveCrossChainMessage.selector),
abi.encode()
);
vm.expectCall(
crossChainController,
0,
abi.encodeWithSelector(ICrossChainReceiver.receiveCrossChainMessage.selector, message, 1)
);
lineaAdapter.receiveMessage(message);
}

function testReceiveWhenRemoteNotTrusted(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
bytes memory message,
address remote
)
public
setLineaAdapter(crossChainController, lineaMessageService, originForwarder, baseGasLimit, 1)
{
vm.assume(remote != originForwarder);
hoax(lineaMessageService);

vm.mockCall(
lineaMessageService,
abi.encodeWithSelector(IMessageService.sender.selector),
abi.encode(remote)
);
vm.expectRevert(bytes(Errors.REMOTE_NOT_TRUSTED));

lineaAdapter.receiveMessage(message);
}

function testReceiveWhenIncorrectOriginChainId(
address crossChainController,
address lineaMessageService,
address originForwarder,
uint256 baseGasLimit,
bytes memory message,
uint256 originChainId
)
public
setLineaAdapter(
crossChainController,
lineaMessageService,
originForwarder,
baseGasLimit,
originChainId
)
{
vm.assume(originChainId != 1);
hoax(lineaMessageService);

vm.mockCall(
lineaMessageService,
abi.encodeWithSelector(IMessageService.sender.selector),
abi.encode(originForwarder)
);
vm.expectRevert(bytes(Errors.REMOTE_NOT_TRUSTED));

lineaAdapter.receiveMessage(message);
}

function _testForwardMessage(Params memory params) internal {
bytes memory message = abi.encode('test message');

hoax(params.caller, 10 ether);

vm.mockCall(
params.lineaMessageService,
abi.encodeWithSelector(IMessageService.sendMessage.selector),
abi.encode()
);
(bool success, bytes memory returnData) = address(lineaAdapter).delegatecall(
abi.encodeWithSelector(
IBaseAdapter.forwardMessage.selector,
params.receiver,
params.dstGasLimit,
ChainIds.LINEA,
message
)
);
vm.clearMockedCalls();

assertEq(success, true);
assertEq(returnData, abi.encode(params.lineaMessageService, 0));
}
}

0 comments on commit a8acb23

Please sign in to comment.