Commit a7fbafa8 authored by Indeavr's avatar Indeavr

(feat): Split OVMMulticall into Multicall (makerdao impl) and OVMContext (used...

(feat): Split OVMMulticall into Multicall (makerdao impl) and OVMContext (used as base contract for OVMContextStorage)
parent e67e8508
---
'@eth-optimism/integration-tests': patch
---
Split OVMMulticall.sol into Multicall.sol & OVMContext.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;
// https://github.com/makerdao/multicall/blob/master/src/Multicall.sol
/// @title Multicall - Aggregate results from multiple read-only function calls
/// @author Michael Elliot <mike@makerdao.com>
/// @author Joshua Levine <joshua@makerdao.com>
/// @author Nick Johnson <arachnid@notdot.net>
contract Multicall {
struct Call {
address target;
bytes callData;
}
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
blockNumber = block.number;
returnData = new bytes[](calls.length);
for (uint256 i = 0; i < calls.length; i++) {
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
require(success);
returnData[i] = ret;
}
}
// Helper functions
function getEthBalance(address addr) public view returns (uint256 balance) {
balance = addr.balance;
}
function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {
blockHash = blockhash(blockNumber);
}
function getLastBlockHash() public view returns (bytes32 blockHash) {
blockHash = blockhash(block.number - 1);
}
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {
timestamp = block.timestamp;
}
function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {
difficulty = block.difficulty;
}
function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {
gaslimit = block.gaslimit;
}
function getCurrentBlockCoinbase() public view returns (address coinbase) {
coinbase = block.coinbase;
}
}
...@@ -22,26 +22,13 @@ pragma solidity ^0.8.9; ...@@ -22,26 +22,13 @@ pragma solidity ^0.8.9;
// Can't do this until the package is published. // Can't do this until the package is published.
//import { iOVM_L1BlockNumber } from "@eth-optimism/contracts/iOVM_L1BlockNumber"; //import { iOVM_L1BlockNumber } from "@eth-optimism/contracts/iOVM_L1BlockNumber";
import { iOVM_L1BlockNumber } from "./OVMContextStorage.sol";
/// @title OVMMulticall - Aggregate results from multiple read-only function calls interface iOVM_L1BlockNumber {
contract OVMMulticall { function getL1BlockNumber() external view returns (uint256);
struct Call { }
address target;
bytes callData;
}
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
blockNumber = block.number;
returnData = new bytes[](calls.length);
for (uint256 i = 0; i < calls.length; i++) {
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
require(success);
returnData[i] = ret;
}
}
// Helper functions /// @title OVMContext - Helper Functions
contract OVMContext {
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {
timestamp = block.timestamp; timestamp = block.timestamp;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.9; pragma solidity ^0.8.9;
// Can't do this until the package is published. import {OVMContext} from "./OVMContext.sol";
//import { iOVM_L1BlockNumber } from "@eth-optimism/contracts/iOVM_L1BlockNumber";
interface iOVM_L1BlockNumber {
function getL1BlockNumber() external view returns (uint256);
}
contract OVMContextStorage { contract OVMContextStorage is OVMContext {
mapping (uint256 => uint256) public l1BlockNumbers; mapping(uint256 => uint256) public l1BlockNumbers;
mapping (uint256 => uint256) public blockNumbers; mapping(uint256 => uint256) public blockNumbers;
mapping (uint256 => uint256) public timestamps; mapping(uint256 => uint256) public timestamps;
mapping (uint256 => uint256) public difficulty; mapping(uint256 => uint256) public difficulty;
mapping (uint256 => address) public coinbases; mapping(uint256 => address) public coinbases;
uint256 public index = 0; uint256 public index = 0;
fallback() external { fallback() external {
l1BlockNumbers[index] = iOVM_L1BlockNumber( l1BlockNumbers[index] = getCurrentL1BlockNumber();
0x4200000000000000000000000000000000000013 blockNumbers[index] = getCurrentBlockNumber();
).getL1BlockNumber(); timestamps[index] = getCurrentBlockTimestamp();
blockNumbers[index] = block.number;
timestamps[index] = block.timestamp;
difficulty[index] = block.difficulty; difficulty[index] = block.difficulty;
coinbases[index] = block.coinbase; coinbases[index] = block.coinbase;
index++; index++;
......
...@@ -23,22 +23,22 @@ describe('OVM Context: Layer 2 EVM Context', () => { ...@@ -23,22 +23,22 @@ describe('OVM Context: Layer 2 EVM Context', () => {
env = await OptimismEnv.new() env = await OptimismEnv.new()
}) })
let OVMMulticall: Contract let Multicall: Contract
let OVMContextStorage: Contract let OVMContextStorage: Contract
beforeEach(async () => { beforeEach(async () => {
const OVMContextStorageFactory = await ethers.getContractFactory( const OVMContextStorageFactory = await ethers.getContractFactory(
'OVMContextStorage', 'OVMContextStorage',
env.l2Wallet env.l2Wallet
) )
const OVMMulticallFactory = await ethers.getContractFactory( const MulticallFactory = await ethers.getContractFactory(
'OVMMulticall', 'Multicall',
env.l2Wallet env.l2Wallet
) )
OVMContextStorage = await OVMContextStorageFactory.deploy() OVMContextStorage = await OVMContextStorageFactory.deploy()
await OVMContextStorage.deployTransaction.wait() await OVMContextStorage.deployTransaction.wait()
OVMMulticall = await OVMMulticallFactory.deploy() Multicall = await MulticallFactory.deploy()
await OVMMulticall.deployTransaction.wait() await Multicall.deployTransaction.wait()
}) })
let numTxs = 5 let numTxs = 5
...@@ -101,21 +101,23 @@ describe('OVM Context: Layer 2 EVM Context', () => { ...@@ -101,21 +101,23 @@ describe('OVM Context: Layer 2 EVM Context', () => {
await dummyTx.wait() await dummyTx.wait()
const block = await L2Provider.getBlockWithTransactions('latest') const block = await L2Provider.getBlockWithTransactions('latest')
const [, returnData] = await OVMMulticall.callStatic.aggregate( const [, returnData] = await Multicall.callStatic.aggregate(
[ [
[ [
OVMMulticall.address, OVMContextStorage.address,
OVMMulticall.interface.encodeFunctionData( OVMContextStorage.interface.encodeFunctionData(
'getCurrentBlockTimestamp' 'getCurrentBlockTimestamp'
), ),
], ],
[ [
OVMMulticall.address, OVMContextStorage.address,
OVMMulticall.interface.encodeFunctionData('getCurrentBlockNumber'), OVMContextStorage.interface.encodeFunctionData(
'getCurrentBlockNumber'
),
], ],
[ [
OVMMulticall.address, OVMContextStorage.address,
OVMMulticall.interface.encodeFunctionData( OVMContextStorage.interface.encodeFunctionData(
'getCurrentL1BlockNumber' 'getCurrentL1BlockNumber'
), ),
], ],
...@@ -141,19 +143,23 @@ describe('OVM Context: Layer 2 EVM Context', () => { ...@@ -141,19 +143,23 @@ describe('OVM Context: Layer 2 EVM Context', () => {
*/ */
it('should return same timestamp and blocknumbers between `eth_call` and `rollup_getInfo`', async () => { it('should return same timestamp and blocknumbers between `eth_call` and `rollup_getInfo`', async () => {
// As atomically as possible, call `rollup_getInfo` and OVMMulticall for the // As atomically as possible, call `rollup_getInfo` and Multicall for the
// blocknumber and timestamp. If this is not atomic, then the sequencer can // blocknumber and timestamp. If this is not atomic, then the sequencer can
// happend to update the timestamp between the `eth_call` and the `rollup_getInfo` // happend to update the timestamp between the `eth_call` and the `rollup_getInfo`
const [info, [, returnData]] = await Promise.all([ const [info, [, returnData]] = await Promise.all([
L2Provider.send('rollup_getInfo', []), L2Provider.send('rollup_getInfo', []),
OVMMulticall.callStatic.aggregate([ Multicall.callStatic.aggregate([
[ [
OVMMulticall.address, OVMContextStorage.address,
OVMMulticall.interface.encodeFunctionData('getCurrentBlockTimestamp'), OVMContextStorage.interface.encodeFunctionData(
'getCurrentBlockTimestamp'
),
], ],
[ [
OVMMulticall.address, OVMContextStorage.address,
OVMMulticall.interface.encodeFunctionData('getCurrentL1BlockNumber'), OVMContextStorage.interface.encodeFunctionData(
'getCurrentL1BlockNumber'
),
], ],
]), ]),
]) ])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment