Skip to content

Instantly share code, notes, and snippets.

@krebernisak
Created August 31, 2021 12:04
Show Gist options
  • Save krebernisak/79437fb0740d3e7a10e9750ee992fab1 to your computer and use it in GitHub Desktop.
Save krebernisak/79437fb0740d3e7a10e9750ee992fab1 to your computer and use it in GitHub Desktop.
Testing L1 initiated L2 ETH withdrawal
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;
import "./ArbSys.sol";
import "./IInbox.sol";
/// @title ArbitrumCrossDomain test contract
contract ArbitrumCrossDomain {
/// @dev Precompiled contract that exists in every Arbitrum chain at address(100). Exposes a variety of system-level functionality.
address constant ARBSYS_ADDR = address(0x0000000000000000000000000000000000000064);
address constant CROSS_DOMAIN_MESSENGER = address(0x578BAde599406A8fE3d24Fd7f7211c0911F5B29e);
address constant public FLAG_ARBITRUM_SEQ_OFFLINE = address(bytes20(bytes32(uint256(keccak256("chainlink.flags.arbitrum-seq-offline")) - 1)));
/**
* @notice emitted when a new gas configuration is set
* @param id maximum cost willing to pay on L2
* @param amount maximum gas price to pay on L2
*/
event WithdrawalFromL2Initiated(
uint256 indexed id,
uint256 amount
);
/**
* @notice withdraws funds from L2 xDomain alias address (representing this L1 contract)
* @dev only owner can call this
* @param amount of funds to withdraws
* @param maxSubmissionCost maximum cost willing to pay on L2
* @param maxGas maximum gas price to pay on L2
* @param gasPriceBid value to send to L2 to cover gas fee
* @param refundAddr address where gas excess on L2 will be sent
*/
function withdrawFundsFromL2(
uint256 amount,
uint256 maxSubmissionCost,
uint256 maxGas,
uint256 gasPriceBid,
address refundAddr
)
external
returns (uint256 id)
{
// We want the L1 to L2 tx to trigger the Arbsys precompile
// then create a L2 to L1 transaction transferring `amount`
bytes memory l1ToL2Calldata = abi.encodeWithSelector(
ArbSys.sendTxToL1.selector,
address(this)
);
id = IInbox(CROSS_DOMAIN_MESSENGER).createRetryableTicketNoRefundAliasRewrite(
ARBSYS_ADDR,
amount,
maxSubmissionCost,
refundAddr,
refundAddr,
maxGas,
gasPriceBid,
l1ToL2Calldata
);
emit WithdrawalFromL2Initiated(id, amount);
}
/// @notice makes this contract payable as it need funds to pay for L2 transactions fees on L1.
receive() external payable {}
/**
* @notice Utility function that converts the `msg.sender` viewed in the L2 to the
* address in the L1 that submitted the xDomain tx
*
* @param l1Sender the address in the L1 that triggered the tx to L2
* @return L2 address as viewed in `msg.sender`
*/
function _generateCrossDomainMessenger(
address l1Sender
)
public
view
virtual
returns (address)
{
uint160 offset = uint160(0x1111000000000000000000000000000000001111);
return address(uint160(l1Sender) - offset);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment