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

bold: diff #55

Closed
wants to merge 2 commits into from
Closed
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
5 changes: 5 additions & 0 deletions src/bridge/Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
rollup = rollup_;
}

/// @notice Allows the proxy owner to set the rollup address
function updateRollupAddress(IOwnable _rollup) external onlyDelegated onlyProxyOwner {
rollup = _rollup;
}

modifier onlyRollupOrOwner() {
if (msg.sender != address(rollup)) {
address rollupOwner = rollup.owner();
Expand Down
2 changes: 2 additions & 0 deletions src/bridge/IBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,6 @@ interface IBridge {
// ---------- initializer ----------

function initialize(IOwnable rollup_) external;

function updateRollupAddress(IOwnable _rollup) external;
}
2 changes: 2 additions & 0 deletions src/bridge/IOutbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ interface IOutbox {
function OUTBOX_VERSION() external view returns (uint128); // the outbox version

function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;

function updateRollupAddress() external;

/// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account
/// When the return value is zero, that means this is a system message
Expand Down
2 changes: 2 additions & 0 deletions src/bridge/ISequencerInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,6 @@ interface ISequencerInbox is IDelayedMessageProvider {
// ---------- initializer ----------

function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external;

function updateRollupAddress() external;
}
79 changes: 1 addition & 78 deletions src/bridge/Inbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
L2MessageType_unsignedEOATx,
L2MessageType_unsignedContractTx
} from "../libraries/MessageTypes.sol";
import {MAX_DATA_SIZE, UNISWAP_L1_TIMELOCK, UNISWAP_L2_FACTORY} from "../libraries/Constants.sol";
import {MAX_DATA_SIZE} from "../libraries/Constants.sol";
import "../precompiles/ArbSys.sol";

import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
Expand Down Expand Up @@ -527,83 +527,6 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
);
}

/// @notice This is an one-time-exception to resolve a misconfiguration of Uniswap Arbitrum deployment
/// Only the Uniswap L1 Timelock may call this function and it is allowed to create a crosschain
/// retryable ticket without address aliasing. More info here:
/// https://gov.uniswap.org/t/consensus-check-fix-the-cross-chain-messaging-bridge-on-arbitrum/18547
/// @dev This function will be removed in future releases
function uniswapCreateRetryableTicket(
address to,
uint256 l2CallValue,
uint256 maxSubmissionCost,
address excessFeeRefundAddress,
address callValueRefundAddress,
uint256 gasLimit,
uint256 maxFeePerGas,
bytes calldata data
) external payable whenNotPaused onlyAllowed returns (uint256) {
// this can only be called by UNISWAP_L1_TIMELOCK
require(msg.sender == UNISWAP_L1_TIMELOCK, "NOT_UNISWAP_L1_TIMELOCK");
// the retryable can only call UNISWAP_L2_FACTORY
require(to == UNISWAP_L2_FACTORY, "NOT_TO_UNISWAP_L2_FACTORY");

// ensure the user's deposit alone will make submission succeed
if (msg.value < (maxSubmissionCost + l2CallValue + gasLimit * maxFeePerGas)) {
revert InsufficientValue(
maxSubmissionCost + l2CallValue + gasLimit * maxFeePerGas,
msg.value
);
}

// if a refund address is a contract, we apply the alias to it
// so that it can access its funds on the L2
// since the beneficiary and other refund addresses don't get rewritten by arb-os
if (AddressUpgradeable.isContract(excessFeeRefundAddress)) {
excessFeeRefundAddress = AddressAliasHelper.applyL1ToL2Alias(excessFeeRefundAddress);
}
if (AddressUpgradeable.isContract(callValueRefundAddress)) {
// this is the beneficiary. be careful since this is the address that can cancel the retryable in the L2
callValueRefundAddress = AddressAliasHelper.applyL1ToL2Alias(callValueRefundAddress);
}

// gas price and limit of 1 should never be a valid input, so instead they are used as
// magic values to trigger a revert in eth calls that surface data without requiring a tx trace
if (gasLimit == 1 || maxFeePerGas == 1)
revert RetryableData(
msg.sender,
to,
l2CallValue,
msg.value,
maxSubmissionCost,
excessFeeRefundAddress,
callValueRefundAddress,
gasLimit,
maxFeePerGas,
data
);

uint256 submissionFee = calculateRetryableSubmissionFee(data.length, block.basefee);
if (maxSubmissionCost < submissionFee)
revert InsufficientSubmissionCost(submissionFee, maxSubmissionCost);

return
_deliverMessage(
L1MessageType_submitRetryableTx,
AddressAliasHelper.undoL1ToL2Alias(msg.sender),
abi.encodePacked(
uint256(uint160(to)),
l2CallValue,
msg.value,
maxSubmissionCost,
uint256(uint160(excessFeeRefundAddress)),
uint256(uint160(callValueRefundAddress)),
gasLimit,
maxFeePerGas,
data.length,
data
)
);
}

function _deliverMessage(
uint8 _kind,
Expand Down
5 changes: 5 additions & 0 deletions src/bridge/Outbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ contract Outbox is DelegateCallAware, IOutbox {
rollup = address(_bridge.rollup());
}

/// @notice Allows the proxy owner to set the rollup address
function updateRollupAddress() external onlyDelegated onlyProxyOwner {
rollup = address(bridge.rollup());
}

function updateSendRoot(bytes32 root, bytes32 l2BlockHash) external {
if (msg.sender != rollup) revert NotRollup(msg.sender, rollup);
roots[root] = l2BlockHash;
Expand Down
47 changes: 39 additions & 8 deletions src/bridge/SequencerInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ import "./IInbox.sol";
import "./ISequencerInbox.sol";
import "../rollup/IRollupLogic.sol";
import "./Messages.sol";
import "../precompiles/ArbGasInfo.sol";
import "../precompiles/ArbSys.sol";

import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol";
import {GasRefundEnabled, IGasRefunder} from "../libraries/IGasRefunder.sol";
import "../libraries/DelegateCallAware.sol";
import "../libraries/ArbitrumChecker.sol";
import {MAX_DATA_SIZE} from "../libraries/Constants.sol";

/**
Expand Down Expand Up @@ -66,6 +69,9 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox

mapping(address => bool) public isSequencer;

// If the chain this SequencerInbox is deployed on is an Arbitrum chain.
bool internal immutable hostChainIsArbitrum = ArbitrumChecker.runningOnArbitrum();

function _chainIdChanged() internal view returns (bool) {
return deployTimeChainId != block.chainid;
}
Expand All @@ -81,6 +87,11 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
maxTimeVariation = maxTimeVariation_;
}

/// @notice Allows the proxy owner to set the rollup address
function updateRollupAddress() external onlyDelegated onlyProxyOwner {
rollup = bridge.rollup();
}

function getTimeBounds() internal view virtual returns (TimeBounds memory) {
TimeBounds memory bounds;
if (block.timestamp > maxTimeVariation.delaySeconds) {
Expand Down Expand Up @@ -387,13 +398,29 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
// this msg isn't included in the current sequencer batch, but instead added to
// the delayed messages queue that is yet to be included
address batchPoster = msg.sender;
bytes memory spendingReportMsg = abi.encodePacked(
block.timestamp,
batchPoster,
dataHash,
seqMessageIndex,
block.basefee
);
bytes memory spendingReportMsg;
if (hostChainIsArbitrum) {
// Include extra gas for the host chain's L1 gas charging
uint256 l1Fees = ArbGasInfo(address(0x6c)).getCurrentTxL1GasFees();
uint256 extraGas = l1Fees / block.basefee;
require(extraGas <= type(uint64).max, "L1_GAS_NOT_UINT64");
spendingReportMsg = abi.encodePacked(
block.timestamp,
batchPoster,
dataHash,
seqMessageIndex,
block.basefee,
uint64(extraGas)
);
} else {
spendingReportMsg = abi.encodePacked(
block.timestamp,
batchPoster,
dataHash,
seqMessageIndex,
block.basefee
);
}
uint256 msgNum = bridge.submitBatchSpendingReport(
batchPoster,
keccak256(spendingReportMsg)
Expand Down Expand Up @@ -433,9 +460,13 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
require(keysetBytes.length < 64 * 1024, "keyset is too large");

if (dasKeySetInfo[ksHash].isValidKeyset) revert AlreadyValidDASKeyset(ksHash);
uint256 creationBlock = block.number;
if (hostChainIsArbitrum) {
creationBlock = ArbSys(address(100)).arbBlockNumber();
}
dasKeySetInfo[ksHash] = DasKeySetInfo({
isValidKeyset: true,
creationBlock: uint64(block.number)
creationBlock: uint64(creationBlock)
});
emit SetValidKeyset(ksHash, keysetBytes);
emit OwnerFunctionCalled(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import "../bridge/IBridge.sol";
import "../bridge/ISequencerInbox.sol";
import "../osp/IOneStepProofEntry.sol";

import "./IChallengeResultReceiver.sol";
import "./IOldChallengeResultReceiver.sol";

import "./ChallengeLib.sol";
import "./OldChallengeLib.sol";

interface IChallengeManager {
interface IOldChallengeManager {
enum ChallengeTerminationType {
TIMEOUT,
BLOCK_PROOF,
Expand Down Expand Up @@ -41,7 +41,7 @@ interface IChallengeManager {
event ChallengeEnded(uint64 indexed challengeIndex, ChallengeTerminationType kind);

function initialize(
IChallengeResultReceiver resultReceiver_,
IOldChallengeResultReceiver resultReceiver_,
ISequencerInbox sequencerInbox_,
IBridge bridge_,
IOneStepProofEntry osp_
Expand All @@ -61,7 +61,7 @@ interface IChallengeManager {
function challengeInfo(uint64 challengeIndex_)
external
view
returns (ChallengeLib.Challenge memory);
returns (OldChallengeLib.Challenge memory);

function currentResponder(uint64 challengeIndex) external view returns (address);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

pragma solidity ^0.8.0;

interface IChallengeResultReceiver {
interface IOldChallengeResultReceiver {
function completeChallenge(
uint256 challengeIndex,
address winner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ pragma solidity ^0.8.0;
import "../state/Machine.sol";
import "../state/GlobalState.sol";

library ChallengeLib {
library OldChallengeLib {
using MachineLib for Machine;
using ChallengeLib for Challenge;
using OldChallengeLib for Challenge;

/// @dev It's assumed that that uninitialzed challenges have mode NONE
enum ChallengeMode {
Expand Down Expand Up @@ -86,8 +86,6 @@ library ChallengeLib {
return keccak256(abi.encodePacked("Machine finished:", globalStateHash));
} else if (status == MachineStatus.ERRORED) {
return keccak256(abi.encodePacked("Machine errored:"));
} else if (status == MachineStatus.TOO_FAR) {
return keccak256(abi.encodePacked("Machine too far:"));
} else {
revert("BAD_BLOCK_STATUS");
}
Expand Down Expand Up @@ -124,8 +122,6 @@ library ChallengeLib {
return keccak256(abi.encodePacked("Block state:", globalStateHash));
} else if (status == MachineStatus.ERRORED) {
return keccak256(abi.encodePacked("Block state, errored:", globalStateHash));
} else if (status == MachineStatus.TOO_FAR) {
return keccak256(abi.encodePacked("Block state, too far:"));
} else {
revert("BAD_BLOCK_STATUS");
}
Expand Down
Loading
Loading