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

feat[contracts]: introduce OVM_GasPriceOracle #912

Merged
merged 6 commits into from
May 20, 2021
Merged
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 .changeset/seven-carpets-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/contracts': patch
---

Introduces the congestion price oracle contract
4 changes: 3 additions & 1 deletion packages/contracts/bin/take-dump.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const CHAIN_ID = env.CHAIN_ID || '420'

// Defaults to 0xFF....FF = *no upgrades*
const L2_CHUG_SPLASH_DEPLOYER_OWNER = env.L2_CHUG_SPLASH_DEPLOYER_OWNER || '0x' + 'FF'.repeat(20)
const GAS_PRICE_ORACLE_OWNER = env.GAS_PRICE_ORACLE_OWNER || '0x' + 'FF'.repeat(20)

/* Internal Imports */
import { makeStateDump } from '../src/state-dump/make-dump'
Expand All @@ -21,7 +22,8 @@ import { RollupDeployConfig } from '../src/contract-deployment'
ovmGlobalContext: {
ovmCHAINID: parseInt(CHAIN_ID, 10),
},
l2ChugSplashDeployerOwner: L2_CHUG_SPLASH_DEPLOYER_OWNER
l2ChugSplashDeployerOwner: L2_CHUG_SPLASH_DEPLOYER_OWNER,
gasPriceOracleOwner: GAS_PRICE_ORACLE_OWNER
}

const dump = await makeStateDump(config as RollupDeployConfig)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT
pragma solidity >0.5.0 <0.8.0;

/* External Imports */
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

/**
* @title OVM_GasPriceOracle
* @dev This contract exposes the current execution price, a measure of how congested the network
* currently is. This measure is used by the Sequencer to determine what fee to charge for
* transactions. When the system is more congested, the execution price will increase and fees
* will also increase as a result.
*
* Compiler used: optimistic-solc
* Runtime target: OVM
*/
contract OVM_GasPriceOracle is Ownable {

/*************
* Variables *
*************/

// Current execution price
uint256 internal executionPrice;

/***************
* Constructor *
***************/

/**
* @param _owner Address that will initially own this contract.
*/
constructor(
address _owner
)
Ownable()
{
transferOwnership(_owner);
}


/********************
* Public Functions *
********************/

/**
* @return Current execution price.
*/
function getExecutionPrice()
public
view
returns (
uint256
)
{
return executionPrice;
}

/**
* Allows the owner to modify the execution price.
* @param _executionPrice New execution price.
*/
function setExecutionPrice(
uint256 _executionPrice
)
public
onlyOwner
{
executionPrice = _executionPrice;
}
}
5 changes: 5 additions & 0 deletions packages/contracts/src/contract-deployment/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface RollupDeployConfig {
allowArbitraryContractDeployment: boolean
}
l2ChugSplashDeployerOwner: string
gasPriceOracleOwner: string
addressManager?: string
dependencies?: string[]
deployOverrides: Overrides
Expand Down Expand Up @@ -268,5 +269,9 @@ export const makeContractDeployConfig = async (
factory: getContractFactory('L2ChugSplashDeployer'),
params: [config.l2ChugSplashDeployerOwner],
},
OVM_GasPriceOracle: {
factory: getContractFactory('OVM_GasPriceOracle'),
params: [config.gasPriceOracleOwner],
},
}
}
1 change: 1 addition & 0 deletions packages/contracts/src/predeploys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ export const predeploys = {
OVM_ExecutionManagerWrapper: '0x420000000000000000000000000000000000000B',
L2ChugSplashDeployer: '0x420000000000000000000000000000000000000D',
L2ChugSplashOwner: '0x420000000000000000000000000000000000000E',
OVM_GasPriceOracle: '0x420000000000000000000000000000000000000F',
ERC1820Registry: '0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24',
}
3 changes: 3 additions & 0 deletions packages/contracts/src/state-dump/make-dump.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,12 @@ export const makeStateDump = async (cfg: RollupDeployConfig): Promise<any> => {
'OVM_ExecutionManagerWrapper',
'L2ChugSplashDeployer',
'L2ChugSplashOwner',
'OVM_GasPriceOracle',
],
deployOverrides: {},
waitForReceipts: false,
l2ChugSplashDeployerOwner: cfg.l2ChugSplashDeployerOwner,
gasPriceOracleOwner: cfg.gasPriceOracleOwner,
}

config = { ...config, ...cfg }
Expand All @@ -159,6 +161,7 @@ export const makeStateDump = async (cfg: RollupDeployConfig): Promise<any> => {
'OVM_ExecutionManagerWrapper',
'L2ChugSplashDeployer',
'L2ChugSplashOwner',
'OVM_GasPriceOracle',
]

const deploymentResult = await deploy(config)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { expect } from '../../../setup'

/* External Imports */
import { ethers } from 'hardhat'
import { ContractFactory, Contract, Signer } from 'ethers'

describe('OVM_GasPriceOracle', () => {
let signer1: Signer
let signer2: Signer
before(async () => {
;[signer1, signer2] = await ethers.getSigners()
})

let Factory__OVM_GasPriceOracle: ContractFactory
before(async () => {
Factory__OVM_GasPriceOracle = await ethers.getContractFactory(
'OVM_GasPriceOracle'
)
})

let OVM_GasPriceOracle: Contract
beforeEach(async () => {
OVM_GasPriceOracle = await Factory__OVM_GasPriceOracle.deploy(
await signer1.getAddress()
)
})

describe('owner', () => {
it('should have an owner', async () => {
expect(await OVM_GasPriceOracle.owner()).to.equal(
await signer1.getAddress()
)
})
})

describe('setExecutionPrice', () => {
it('should revert if called by someone other than the owner', async () => {
await expect(OVM_GasPriceOracle.connect(signer2).setExecutionPrice(1234))
.to.be.reverted
})

it('should succeed if called by the owner', async () => {
await expect(OVM_GasPriceOracle.connect(signer1).setExecutionPrice(1234))
.to.not.be.reverted
})
})

describe('getExecutionPrice', () => {
it('should return zero at first', async () => {
expect(await OVM_GasPriceOracle.getExecutionPrice()).to.equal(0)
})

it('should change when setExecutionPrice is called', async () => {
const executionPrice = 1234

await OVM_GasPriceOracle.connect(signer1).setExecutionPrice(
executionPrice
)

expect(await OVM_GasPriceOracle.getExecutionPrice()).to.equal(
executionPrice
)
})

it('is the 1st storage slot', async () => {
const executionPrice = 1234
const slot = 1

// set the price
await OVM_GasPriceOracle.connect(signer1).setExecutionPrice(
executionPrice
)

// get the storage slot value
const priceAtSlot = await signer1.provider.getStorageAt(
OVM_GasPriceOracle.address,
slot
)
expect(await OVM_GasPriceOracle.getExecutionPrice()).to.equal(
ethers.BigNumber.from(priceAtSlot)
)
})
})
})