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

Abdk fix #86

Merged
merged 33 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3e3d299
fix: abdk-cvf-3
zkbenny Mar 21, 2024
389322a
fix: abdk-cvf-4
zkbenny Mar 21, 2024
123377e
fix: abdk-cvf-5
zkbenny Mar 21, 2024
7681fac
fix: abdk-cvf-6
zkbenny Mar 21, 2024
d059105
fix: abdk-cvf-7
zkbenny Mar 21, 2024
935b1b1
fix: abdk-cvf-11
zkbenny Mar 21, 2024
9bed074
fix: abdk-cvf-13
zkbenny Mar 21, 2024
44b9cc8
fix: abdk-cvf-14
zkbenny Mar 22, 2024
80fedf4
fix: abdk-cvf-15
zkbenny Mar 22, 2024
c2e2548
fix: abdk-cvf-18
zkbenny Mar 22, 2024
357b822
fix: abdk-cvf-19
zkbenny Mar 22, 2024
b346e6c
fix: abdk-cvf-20
zkbenny Mar 22, 2024
12739ed
fix: abdk-cvf-23
zkbenny Mar 22, 2024
72b0291
fix: abdk-cvf-24
zkbenny Mar 22, 2024
854f346
fix: abdk-cvf-26
zkbenny Mar 22, 2024
d9e34bd
fix: abdk-cvf-29
zkbenny Mar 22, 2024
457343d
fix: abdk-cvf-37
zkbenny Mar 22, 2024
8d991a6
fix: abdk-cvf-43
zkbenny Mar 22, 2024
e510901
fix: abdk-cvf-46
zkbenny Mar 22, 2024
c48bc5a
fix: abdk-cvf-47
zkbenny Mar 22, 2024
9a957d6
fix: abdk-cvf-48
zkbenny Mar 22, 2024
f52b6da
fix: abdk-cvf-50
zkbenny Mar 22, 2024
46ebcc2
fix: abdk-cvf-51
zkbenny Mar 22, 2024
ccf51b7
fix: abdk-cvf-53
zkbenny Mar 22, 2024
06b900e
fix: abdk-cvf-54
zkbenny Mar 22, 2024
14f074b
fix: abdk-cvf-56
zkbenny Mar 22, 2024
f13b440
fix: abdk-cvf-57
zkbenny Mar 22, 2024
999e036
fix: abdk-cvf-59
zkbenny Mar 22, 2024
103b4a8
fix: abdk-cvf-60
zkbenny Mar 22, 2024
7cbeb08
fix: abdk-cvf-61
zkbenny Mar 22, 2024
65cecf4
fix: abdk-cvf-62
zkbenny Mar 22, 2024
fba01f8
fix: abdk-cvf-2
zkbenny Mar 22, 2024
7813bdb
fix: abdk-cvf-7
zkbenny Mar 22, 2024
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
41 changes: 24 additions & 17 deletions contracts/Arbitrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ contract Arbitrator is IArbitrator, OwnableUpgradeable, UUPSUpgradeable, Reentra
uint256[50] private __gap;

/// @notice Primary chain gateway init
event InitPrimaryChain(IL1Gateway gateway);
event InitPrimaryChain(IL1Gateway indexed gateway);
/// @notice SecondaryChain's status changed
event SecondaryChainStatusUpdate(IL1Gateway gateway, bool isActive);
event SecondaryChainStatusUpdate(IL1Gateway indexed gateway, bool isActive);
/// @notice Relayer's status changed
event RelayerStatusUpdate(address relayer, bool isActive);
event RelayerStatusUpdate(address indexed relayer, bool isActive);
/// @notice Validator's status changed
event ValidatorStatusUpdate(IL1Gateway gateway, address validatorAddress, bool isActive);
event ValidatorStatusUpdate(IL1Gateway indexed gateway, address validatorAddress, bool isActive);
/// @notice Fee params for L1->L2 transactions changed
event NewFeeParams(IL1Gateway gateway, FeeParams newFeeParams);
event NewFeeParams(IL1Gateway indexed gateway, FeeParams newFeeParams);
/// @notice Emit when receive message from l1 gateway
event MessageReceived(uint256 value, bytes callData);
/// @notice Emit when forward message to l1 gateway
event MessageForwarded(IL1Gateway gateway, uint256 value, bytes callData);
event MessageForwarded(IL1Gateway indexed gateway, uint256 value, bytes callData);

/// @notice Checks if relayer is active
modifier onlyRelayer() {
Expand All @@ -60,12 +60,14 @@ contract Arbitrator is IArbitrator, OwnableUpgradeable, UUPSUpgradeable, Reentra
}

function initialize() external initializer {
__Ownable_init();
__UUPSUpgradeable_init();
__ReentrancyGuard_init();
__Ownable_init_unchained();
__UUPSUpgradeable_init_unchained();
__ReentrancyGuard_init_unchained();
}

function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {
// can only call by owner
}

/// @notice Return the message hash at a position stored in queue
function getMessageHash(IL1Gateway _gateway, uint256 _index) external view returns (bytes32 messageHash) {
Expand All @@ -79,6 +81,7 @@ contract Arbitrator is IArbitrator, OwnableUpgradeable, UUPSUpgradeable, Reentra
/// @dev Set primary chain
function setPrimaryChainGateway(IL1Gateway _gateway) external onlyOwner {
require(address(primaryChainGateway) == address(0), "Duplicate init gateway");
require(address(_gateway) != address(0), "Invalid gateway");
primaryChainGateway = _gateway;
emit InitPrimaryChain(_gateway);
}
Expand All @@ -90,17 +93,21 @@ contract Arbitrator is IArbitrator, OwnableUpgradeable, UUPSUpgradeable, Reentra
bytes calldata _adapterParams
) external payable onlyOwner {
require(_gateway != primaryChainGateway, "Invalid gateway");
secondaryChainGateways[_gateway] = _active;
bytes memory callData = abi.encodeCall(IZkSync.setSecondaryChainGateway, (address(_gateway), _active));
// Forward fee to send message
primaryChainGateway.sendMessage{value: msg.value}(0, callData, _adapterParams);
emit SecondaryChainStatusUpdate(_gateway, _active);
if (_active != secondaryChainGateways[_gateway]) {
secondaryChainGateways[_gateway] = _active;
bytes memory callData = abi.encodeCall(IZkSync.setSecondaryChainGateway, (address(_gateway), _active));
// Forward fee to send message
primaryChainGateway.sendMessage{value: msg.value}(0, callData, _adapterParams);
emit SecondaryChainStatusUpdate(_gateway, _active);
}
}

/// @dev Set relayer
function setRelayer(address _relayer, bool _active) external onlyOwner {
relayers[_relayer] = _active;
emit RelayerStatusUpdate(_relayer, _active);
if (relayers[_relayer] != _active) {
relayers[_relayer] = _active;
emit RelayerStatusUpdate(_relayer, _active);
}
}

/// @dev Set validator for a chain
Expand Down
58 changes: 38 additions & 20 deletions contracts/ZkLink.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ contract ZkLink is
{
using UncheckedMath for uint256;

// keccak256("ForwardL2Request(address gateway,bool isContractCall,address sender,uint256 txId,address contractAddressL2,uint256 l2Value,bytes32 l2CallDataHash,uint256 l2GasLimit,uint256 l2GasPricePerPubdata,bytes32 factoryDepsHash,address refundRecipient)")
/// @dev The forward request type hash
bytes32 public constant FORWARD_REQUEST_TYPE_HASH =
0xe0aaca1722ef50bb0c9b032e5b16ce2b79fa9f23638835456b27fd6894f8292c;
keccak256(
"ForwardL2Request(address gateway,bool isContractCall,address sender,uint256 txId,address contractAddressL2,uint256 l2Value,bytes32 l2CallDataHash,uint256 l2GasLimit,uint256 l2GasPricePerPubdata,bytes32 factoryDepsHash,address refundRecipient)"
);

/// @dev The length of withdraw message sent to secondary chain
uint256 private constant L2_WITHDRAW_MESSAGE_LENGTH = 108;

/// @dev Whether eth is the gas token
bool public immutable IS_ETH_GAS_TOKEN;
Expand Down Expand Up @@ -87,13 +92,13 @@ contract ZkLink is
uint256[50] private __gap;

/// @notice Gateway init
event InitGateway(IL2Gateway gateway);
event InitGateway(IL2Gateway indexed gateway);
/// @notice Contract's permit status changed
event ContractAllowStatusUpdate(address contractAddress, bool isPermit);
event ContractAllowStatusUpdate(address indexed contractAddress, bool isPermit);
/// @notice Tx gas price changed
event TxGasPriceUpdate(uint256 oldTxGasPrice, uint256 newTxGasPrice);
/// @notice Validator's status changed
event ValidatorStatusUpdate(address validatorAddress, bool isActive);
event ValidatorStatusUpdate(address indexed validatorAddress, bool isActive);
/// @notice Fee params for L1->L2 transactions changed
event NewFeeParams(FeeParams oldFeeParams, FeeParams newFeeParams);
/// @notice New priority request event. Emitted when a request is placed into the priority queue
Expand All @@ -105,7 +110,7 @@ contract ZkLink is
/// @notice Emitted when receive l2 tx hash from primary chain.
event SyncL2TxHash(bytes32 l2TxHash, bytes32 primaryChainL2TxHash);
/// @notice Emitted when validator withdraw forward fee
event WithdrawForwardFee(address receiver, uint256 amount);
event WithdrawForwardFee(address indexed receiver, uint256 amount);
/// @notice Emitted when the withdrawal is finalized on L1 and funds are released.
/// @param to The address to which the funds were sent
/// @param amount The amount of funds that were sent
Expand Down Expand Up @@ -137,13 +142,15 @@ contract ZkLink is
}

function initialize() external initializer {
__Ownable_init();
__UUPSUpgradeable_init();
__ReentrancyGuard_init();
__Pausable_init();
__Ownable_init_unchained();
__UUPSUpgradeable_init_unchained();
__ReentrancyGuard_init_unchained();
__Pausable_init_unchained();
}

function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {
// can only called by owner
}

/// @dev Pause the contract, can only be called by the owner
function pause() external onlyOwner {
Expand Down Expand Up @@ -186,28 +193,36 @@ contract ZkLink is
/// @dev Init gateway, can only be called by the owner
function setGateway(IL2Gateway _gateway) external onlyOwner {
require(address(gateway) == address(0), "Duplicate init gateway");
require(address(_gateway) != address(0), "Invalid gateway");
gateway = _gateway;
emit InitGateway(_gateway);
}

/// @dev Update the permit status of contract, can only be called by the owner
function setAllowList(address _contractAddress, bool _permitted) external onlyOwner {
allowLists[_contractAddress] = _permitted;
emit ContractAllowStatusUpdate(_contractAddress, _permitted);
if (allowLists[_contractAddress] != _permitted) {
allowLists[_contractAddress] = _permitted;
emit ContractAllowStatusUpdate(_contractAddress, _permitted);
}
}

/// @dev Update the tx gas price
function setTxGasPrice(uint256 _newTxGasPrice) external onlyOwner {
uint256 oldTxGasPrice = txGasPrice;
txGasPrice = _newTxGasPrice;
emit TxGasPriceUpdate(oldTxGasPrice, _newTxGasPrice);
if (oldTxGasPrice != _newTxGasPrice) {
txGasPrice = _newTxGasPrice;
emit TxGasPriceUpdate(oldTxGasPrice, _newTxGasPrice);
}
}

function setValidator(address _validator, bool _active) external onlyGateway {
validators[_validator] = _active;
emit ValidatorStatusUpdate(_validator, _active);
if (validators[_validator] != _active) {
validators[_validator] = _active;
emit ValidatorStatusUpdate(_validator, _active);
}
}

/// @dev https://github.com/matter-labs/era-contracts/blob/e0a33ce73c4decd381446a6eb812b14c2ff69c47/l1-contracts/contracts/zksync/facets/Admin.sol#L88
function changeFeeParams(FeeParams calldata _newFeeParams) external onlyGateway {
// Double checking that the new fee params are valid, i.e.
// the maximal pubdata per batch is not less than the maximal pubdata per priority transaction.
Expand All @@ -223,8 +238,10 @@ contract ZkLink is
function setForwardFeeAllocator(address _newForwardFeeAllocator) external onlyOwner {
require(_newForwardFeeAllocator != address(0), "Invalid allocator");
address oldAllocator = forwardFeeAllocator;
forwardFeeAllocator = _newForwardFeeAllocator;
emit ForwardFeeAllocatorUpdate(oldAllocator, _newForwardFeeAllocator);
if (oldAllocator != _newForwardFeeAllocator) {
forwardFeeAllocator = _newForwardFeeAllocator;
emit ForwardFeeAllocatorUpdate(oldAllocator, _newForwardFeeAllocator);
}
}

function l2TransactionBaseCost(
Expand Down Expand Up @@ -460,6 +477,7 @@ contract ZkLink is
}

/// @notice Derives the price for L2 gas in ETH to be paid.
/// @dev https://github.com/matter-labs/era-contracts/blob/e0a33ce73c4decd381446a6eb812b14c2ff69c47/l1-contracts/contracts/zksync/facets/Mailbox.sol#L147
/// @param _l1GasPrice The gas price on L1.
/// @param _gasPerPubdata The price for each pubdata byte in L2 gas
/// @return The price of L2 gas in ETH
Expand Down Expand Up @@ -555,7 +573,7 @@ contract ZkLink is
// bytes4 function signature + address l1Gateway + uint256 amount + address l2Sender + bytes _additionalData
// (where the _additionalData = abi.encode(l1Receiver))
// = 4 + 20 + 32 + 20 + 32 == 108 (bytes).
require(_message.length == 108, "pm");
require(_message.length == L2_WITHDRAW_MESSAGE_LENGTH, "pm");

(uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_message, 0);
require(bytes4(functionSignature) == this.finalizeEthWithdrawal.selector, "is");
Expand Down
5 changes: 3 additions & 2 deletions contracts/gateway/BaseGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ abstract contract BaseGateway is IGateway, OwnableUpgradeable, UUPSUpgradeable,
*/
uint256[49] private __gap;

event SetRemoteGateway(address remoteGateWay);
event NewRemoteGateway(address remoteGateWay);

function __BaseGateway_init() internal onlyInitializing {
__BaseGateway_init_unchained();
Expand All @@ -39,7 +39,8 @@ abstract contract BaseGateway is IGateway, OwnableUpgradeable, UUPSUpgradeable,
/// @param _remoteGateway remote gateway address
function setRemoteGateway(address _remoteGateway) external onlyOwner {
require(remoteGateway == address(0), "Duplicate init remote gateway");
require(_remoteGateway != address(0), "Invalid gateway");
remoteGateway = _remoteGateway;
emit SetRemoteGateway(_remoteGateway);
emit NewRemoteGateway(_remoteGateway);
}
}
2 changes: 0 additions & 2 deletions contracts/gateway/L2BaseGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ abstract contract L2BaseGateway is IL2Gateway {
*/
uint256[50] private __gap;

event L2GatewayMessageSent(uint256 value, bytes callData);

/// @dev Ensure withdraw come from zkLink
modifier onlyZkLink() {
require(msg.sender == ZKLINK, "Not zkLink contract");
Expand Down
9 changes: 6 additions & 3 deletions contracts/gateway/optimism/OptimismL2Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import {OptimismGateway} from "./OptimismGateway.sol";
import {L2BaseGateway} from "../L2BaseGateway.sol";

contract OptimismL2Gateway is L2BaseGateway, OptimismGateway {
constructor(
address _zkLink
) L2BaseGateway(_zkLink) OptimismGateway(IOptimismMessenger(0x4200000000000000000000000000000000000007)) {
/// @dev The L2CrossDomainMessenger deployed on OP
/// see https://docs.optimism.io/chain/addresses
IOptimismMessenger private constant L2_CROSS_DOMAIN_MESSENGER =
IOptimismMessenger(0x4200000000000000000000000000000000000007);

constructor(address _zkLink) L2BaseGateway(_zkLink) OptimismGateway(L2_CROSS_DOMAIN_MESSENGER) {
_disableInitializers();
}

Expand Down
2 changes: 2 additions & 0 deletions contracts/gateway/scroll/ScrollL1Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
executeData,
_finalizeMessageGasLimit,
// solhint-disable-next-line avoid-tx-origin
// The origin address paid the network fees of L2 on L1
// So the origin address is set as the refund address for the excess network fees on L2.
tx.origin

Check warning on line 38 in contracts/gateway/scroll/ScrollL1Gateway.sol

View workflow job for this annotation

GitHub Actions / Test solidity contracts

Avoid to use tx.origin
);
}

Expand Down
7 changes: 2 additions & 5 deletions contracts/gateway/zkpolygon/ZkPolygonL1Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,16 @@ contract ZkPolygonL1Gateway is IBridgeMessageReceiver, L1BaseGateway, BaseGatewa
/// @notice ZkPolygon message service on local chain
IZkPolygon public immutable MESSAGE_SERVICE;

/// @dev The destination network of Polygon zkEVM
uint32 public constant ETH_NETWORK_ID = 1;
// Default to true
// @dev Set to true for claiming asset on the destination network
bool public constant FORCE_UPDATE_GLOBAL_EXIT_ROOT = true;

modifier onlyMessageService() {
require(msg.sender == address(MESSAGE_SERVICE), "Not remote gateway");
_;
}

/// @dev A mapping L2 batch number => message number => flag
/// @dev Used to indicate that zkSync L2 -> L1 message was already processed
mapping(uint256 => mapping(uint256 => bool)) public isMessageFinalized;

constructor(IArbitrator _arbitrator, IZkPolygon _messageService) L1BaseGateway(_arbitrator) {
_disableInitializers();
MESSAGE_SERVICE = _messageService;
Expand Down
3 changes: 2 additions & 1 deletion contracts/gateway/zkpolygon/ZkPolygonL2Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ contract ZkPolygonL2Gateway is IBridgeMessageReceiver, L2BaseGateway, BaseGatewa
/// @notice ZkPolygon message service on local chain
IZkPolygon public immutable MESSAGE_SERVICE;

/// @dev The destination network of Ethereum
uint32 public constant ETH_NETWORK_ID = 0;
// Default to true
// @dev Set to true for claiming asset on the destination network
bool public constant FORCE_UPDATE_GLOBAL_EXIT_ROOT = true;

/// @dev Modifier to make sure the original sender is messageService on remote chain.
Expand Down
11 changes: 9 additions & 2 deletions contracts/gateway/zksync/ZkSyncL1Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import {L2_ETH_TOKEN_SYSTEM_CONTRACT_ADDR} from "../../zksync/l1-contracts/common/L2ContractAddresses.sol";

contract ZkSyncL1Gateway is IZkSyncL1Gateway, L1BaseGateway, BaseGateway {
/// @dev The L2 eth withdraw message minimum length
uint256 private constant L2_ETH_WITHDRAW_MESSAGE_MINIMUM_LENGTH = 108;

/// @notice ZkSync message service on local chain
IMailbox public immutable MESSAGE_SERVICE;

Expand All @@ -26,7 +29,9 @@
}

/// @dev Receive eth from zkSync canonical bridge
receive() external payable {}
receive() external payable {
// nothing to do here
}

function initialize() external initializer {
__BaseGateway_init();
Expand All @@ -48,7 +53,9 @@
_l2GasPerPubdataByteLimit,
new bytes[](0),
// solhint-disable-next-line avoid-tx-origin
// The origin address paid the network fees of L2 on L1
// So the origin address is set as the refund address for the excess network fees on L2.
tx.origin

Check warning on line 58 in contracts/gateway/zksync/ZkSyncL1Gateway.sol

View workflow job for this annotation

GitHub Actions / Test solidity contracts

Avoid to use tx.origin
);
}

Expand Down Expand Up @@ -108,7 +115,7 @@
// additionalData (sendMessage): l2Value + l2CallData >= 32 (bytes)
// It should be equal to the length of the function signature + eth receiver address + uint256 amount + l2Sender
// + additionalData >= 4 + 20 + 32 + 20 + 32 = 108 (bytes).
require(_message.length >= 108, "Incorrect message length");
require(_message.length >= L2_ETH_WITHDRAW_MESSAGE_MINIMUM_LENGTH, "Incorrect message length");

(uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_message, 0);
require(bytes4(functionSignature) == IMailbox.finalizeEthWithdrawal.selector, "Incorrect function selector");
Expand Down
4 changes: 0 additions & 4 deletions contracts/gateway/zksync/ZkSyncL2Gateway.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.0;

import {IL2Messenger} from "../../interfaces/zksync/IL2Messenger.sol";
import {IL2ETHToken} from "../../interfaces/zksync/IL2ETHToken.sol";
import {L2BaseGateway} from "../L2BaseGateway.sol";
import {AddressAliasHelper} from "../../zksync/l1-contracts/vendor/AddressAliasHelper.sol";
Expand All @@ -11,9 +10,6 @@ import {BaseGateway} from "../BaseGateway.sol";
contract ZkSyncL2Gateway is IMessageClaimer, L2BaseGateway, BaseGateway {
uint160 internal constant SYSTEM_CONTRACTS_OFFSET = 0x8000; // 2^15

/// @notice ZkSync system message service on local chain
IL2Messenger public constant L2_MESSENGER = IL2Messenger(address(SYSTEM_CONTRACTS_OFFSET + 0x08));

/// @notice ZkSync eth bridge service on local chain
IL2ETHToken public constant L2_ETH_ADDRESS = IL2ETHToken(address(SYSTEM_CONTRACTS_OFFSET + 0x0a));

Expand Down
3 changes: 3 additions & 0 deletions contracts/interfaces/IL2Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ pragma solidity ^0.8.0;
import {IGateway} from "./IGateway.sol";

interface IL2Gateway is IGateway {
/// @notice Emit when sending a message
event L2GatewayMessageSent(uint256 value, bytes callData);

/// @notice Send message to remote gateway
/// @param _value The msg value
/// @param _callData The call data
Expand Down
2 changes: 1 addition & 1 deletion contracts/interfaces/linea/IL2MessageService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ pragma solidity ^0.8.0;
import {IMessageService} from "./IMessageService.sol";

interface IL2MessageService is IMessageService {
/// @notice Returns coinbase fee when sendMessage
/// @notice Returns the fee charged by Linea canonical message service when sending a message
function minimumFeeInWei() external view returns (uint256);
}
Loading
Loading