-
Notifications
You must be signed in to change notification settings - Fork 0
make mintTransaction
called via CrossDomainMessenger
#80
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
base: op-es
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,9 @@ import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPort | |
/// for sending and receiving data on the L1 side. Users are encouraged to use this | ||
/// interface instead of interacting with lower-level contracts directly. | ||
contract L1CrossDomainMessenger is CrossDomainMessenger, ProxyAdminOwnedBase, ReinitializableBase, ISemver { | ||
/// @notice Thrown when the caller is not the minter. | ||
error L1CrossDomainMessenger_NotMinter(); | ||
|
||
/// @custom:legacy | ||
/// @custom:spacer superchainConfig | ||
/// @notice Spacer taking up the legacy `superchainConfig` slot. | ||
|
@@ -42,6 +45,9 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ProxyAdminOwnedBase, Re | |
/// @notice Contract of the SystemConfig. | ||
ISystemConfig public systemConfig; | ||
|
||
/// @notice Emitted when a minter is set. | ||
event MinterSet(address indexed minter); | ||
|
||
/// @notice Constructs the L1CrossDomainMessenger contract. | ||
constructor() ReinitializableBase(2) { | ||
_disableInitializers(); | ||
|
@@ -89,6 +95,64 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ProxyAdminOwnedBase, Re | |
return portal; | ||
} | ||
|
||
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.L1CrossDomainMessenger.QKCConfigStorage")) - 1)) & | ||
// ~bytes32(uint256(0xff)) | ||
bytes32 private constant _QKC_CONFIG_STORAGE_LOCATION = | ||
0x21f30a216d738aeb55799dae7148f127e3b8f70b0224a5edb846c108cd573c00; | ||
/// @custom:storage-location erc7201:openzeppelin.storage.L1CrossDomainMessenger.QKCConfigStorage | ||
|
||
struct QKCConfigStorage { | ||
/// @notice The minter for migrating existing L1 token to L2 native token. | ||
address minter; | ||
} | ||
|
||
function _getQKCConfigStorage() private pure returns (QKCConfigStorage storage $) { | ||
assembly { | ||
$.slot := _QKC_CONFIG_STORAGE_LOCATION | ||
} | ||
} | ||
|
||
/// @notice Add a minter to the L1CrossDomainMessenger contract. To disable, set an empty value. | ||
function setMinter(address _minter) external { | ||
_assertOnlyProxyAdminOrProxyAdminOwner(); | ||
QKCConfigStorage storage $ = _getQKCConfigStorage(); | ||
$.minter = _minter; | ||
emit MinterSet(_minter); | ||
} | ||
|
||
/// @notice Triggers a QKC mint message via the relayMessage function on L2. Can only be called by the minter. | ||
/// @dev This function can only be called by the minter. | ||
/// @param _target Target contract or wallet address. | ||
/// @param _message Message to trigger the target address with. | ||
/// @param _mintValue Value to mint. | ||
/// @param _minGasLimit Minimum gas limit that the message can be executed with. | ||
function sendMintMessage( | ||
address _target, | ||
bytes calldata _message, | ||
uint256 _mintValue, | ||
uint32 _minGasLimit | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're using RECEIVE_DEFAULT_GAS_LIMIT, is there still a need to include the _minGasLimit parameter? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like the existing |
||
) | ||
external | ||
{ | ||
QKCConfigStorage storage $ = _getQKCConfigStorage(); | ||
if (msg.sender != $.minter) { | ||
revert L1CrossDomainMessenger_NotMinter(); | ||
} | ||
|
||
portal.mintTransaction({ | ||
_to: address(otherMessenger), | ||
_mintValue: _mintValue, | ||
_gasLimit: baseGas(_message, _minGasLimit), | ||
_data: abi.encodeWithSelector( | ||
this.relayMessage.selector, messageNonce(), msg.sender, _target, _mintValue, _minGasLimit, _message | ||
) | ||
}); | ||
|
||
unchecked { | ||
++msgNonce; | ||
} | ||
} | ||
|
||
/// @inheritdoc CrossDomainMessenger | ||
function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override { | ||
portal.depositTransaction{ value: _value }({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ import { GameStatus, GameType } from "src/dispute/lib/Types.sol"; | |
import { ISemver } from "interfaces/universal/ISemver.sol"; | ||
import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; | ||
import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; | ||
import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; | ||
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; | ||
import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; | ||
import { IL2ToL1MessagePasser } from "interfaces/L2/IL2ToL1MessagePasser.sol"; | ||
|
@@ -137,8 +138,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase | |
/// @custom:storage-location erc7201:openzeppelin.storage.OptimismPortal2.QKCConfigStorage | ||
|
||
struct QKCConfigStorage { | ||
/// @notice The minter for migrating existing L1 token to L2 native token. | ||
address minter; | ||
address spacer_for_minter;// should not be used again | ||
bool disableNativeDeposit; | ||
} | ||
|
||
|
@@ -191,8 +191,6 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase | |
IAnchorStateRegistry newAnchorStateRegistry | ||
); | ||
|
||
/// @notice Emitted when a minter is set. | ||
event MinterSet(address indexed minter); | ||
/// @notice Emitted when native deposit is disabled. | ||
event NativeDepositDisabled(); | ||
/// @notice Emitted when native deposit is enabled. | ||
|
@@ -760,34 +758,39 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase | |
} | ||
} | ||
|
||
/// @notice Add a minter to the OptimismPortal contract. To disable, set an empty value. | ||
function setMinter(address _minter) external { | ||
if (msg.sender != proxyAdminOwner()) { | ||
revert OptimismPortal_Unauthorized(); | ||
} | ||
QKCConfigStorage storage $ = _getQKCConfigStorage(); | ||
$.minter = _minter; | ||
emit MinterSet(_minter); | ||
} | ||
|
||
/// @notice Mint a specific amount of L2 native token to an address. | ||
function mintTransaction(address _to, uint256 _value) external metered(RECEIVE_DEFAULT_GAS_LIMIT) { | ||
QKCConfigStorage storage $ = _getQKCConfigStorage(); | ||
if (msg.sender != $.minter) { | ||
/// @dev This function is only callable by L1CrossDomainMessenger. | ||
function mintTransaction( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It appears that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to keep |
||
address _to, | ||
uint256 _mintValue, | ||
uint64 _gasLimit, | ||
bytes memory _data | ||
) | ||
external | ||
metered(_gasLimit) | ||
{ | ||
// Can only be called by L1CrossDomainMessenger | ||
address l1CrossDomainMessenger = systemConfig.l1CrossDomainMessenger(); | ||
if (msg.sender != l1CrossDomainMessenger) { | ||
revert OptimismPortal_Unauthorized(); | ||
} | ||
|
||
if (_to == address(0)) { | ||
revert OptimismPortal_BadTarget(); | ||
// Prevent depositing transactions that have too small of a gas limit. Users should pay | ||
// more for more resource usage. | ||
if (_gasLimit < minimumGasLimit(uint64(_data.length))) { | ||
revert OptimismPortal_GasLimitTooLow(); | ||
} | ||
|
||
address from = AddressAliasHelper.applyL1ToL2Alias(msg.sender); | ||
|
||
// Compute the opaque data that will be emitted as part of the TransactionDeposited event. | ||
// We use opaque data so that we can update the TransactionDeposited event in the future | ||
// without breaking the current interface. | ||
bytes memory opaqueData = abi.encodePacked(_value, _value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes("")); | ||
bytes memory opaqueData = abi.encodePacked(_mintValue, _mintValue, _gasLimit, false, _data); | ||
|
||
// Emit a TransactionDeposited event so that the rollup node can derive a deposit | ||
// transaction for this deposit. | ||
emit TransactionDeposited(Constants.QKC_DEPOSITOR_ACCOUNT, _to, DEPOSIT_VERSION, opaqueData); | ||
emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData); | ||
} | ||
|
||
/// @notice set native deposit flag. Pass true to disable. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the method is intended solely for minting QKC, we should omit this parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It tries to be flexible, e.g., it's possible to mint and swap in a single L2 transaction if we want it in future.