Commit 912ab681 authored by smartcontracts's avatar smartcontracts Committed by Kelvin Fichter

feat[contracts]: introduce OVM_GasPriceOracle (#912)

* feat[contracts]: congestion price oracle

* chore: add changeset

* contracts: gas price oracle (#917)

* contracts: gas price oracle

* tests: update

* fees: fix tests

* contracts: simplify gas price oracle

* lint: fix

* test: execution price is at the 1st storage slot

* chore: rename predeploy to GasPriceOracle

* chore: rename gas price oracle test name
Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
Co-authored-by: default avatarGeorgios Konstantopoulos <me@gakonst.com>
parent 25a5dbdd
---
'@eth-optimism/contracts': patch
---
Introduces the congestion price oracle contract
...@@ -5,6 +5,7 @@ import * as mkdirp from 'mkdirp' ...@@ -5,6 +5,7 @@ import * as mkdirp from 'mkdirp'
const env = process.env const env = process.env
const CHAIN_ID = env.CHAIN_ID || '420' const CHAIN_ID = env.CHAIN_ID || '420'
const GAS_PRICE_ORACLE_OWNER = env.GAS_PRICE_ORACLE_OWNER || '0x' + 'FF'.repeat(20)
/* Internal Imports */ /* Internal Imports */
import { makeStateDump } from '../src/state-dump/make-dump' import { makeStateDump } from '../src/state-dump/make-dump'
...@@ -18,6 +19,7 @@ import { RollupDeployConfig } from '../src/contract-deployment' ...@@ -18,6 +19,7 @@ import { RollupDeployConfig } from '../src/contract-deployment'
ovmGlobalContext: { ovmGlobalContext: {
ovmCHAINID: parseInt(CHAIN_ID, 10), ovmCHAINID: parseInt(CHAIN_ID, 10),
}, },
gasPriceOracleOwner: GAS_PRICE_ORACLE_OWNER
} }
const dump = await makeStateDump(config as RollupDeployConfig) const dump = await makeStateDump(config as RollupDeployConfig)
......
// 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;
}
}
...@@ -34,6 +34,7 @@ export interface RollupDeployConfig { ...@@ -34,6 +34,7 @@ export interface RollupDeployConfig {
owner: string | Signer owner: string | Signer
allowArbitraryContractDeployment: boolean allowArbitraryContractDeployment: boolean
} }
gasPriceOracleOwner: string
addressManager?: string addressManager?: string
dependencies?: string[] dependencies?: string[]
deployOverrides: Overrides deployOverrides: Overrides
...@@ -258,5 +259,9 @@ export const makeContractDeployConfig = async ( ...@@ -258,5 +259,9 @@ export const makeContractDeployConfig = async (
true true
), ),
}, },
OVM_GasPriceOracle: {
factory: getContractFactory('OVM_GasPriceOracle'),
params: [config.gasPriceOracleOwner],
},
} }
} }
...@@ -18,5 +18,6 @@ export const predeploys = { ...@@ -18,5 +18,6 @@ export const predeploys = {
Lib_AddressManager: '0x4200000000000000000000000000000000000008', Lib_AddressManager: '0x4200000000000000000000000000000000000008',
OVM_ProxyEOA: '0x4200000000000000000000000000000000000009', OVM_ProxyEOA: '0x4200000000000000000000000000000000000009',
OVM_ExecutionManagerWrapper: '0x420000000000000000000000000000000000000B', OVM_ExecutionManagerWrapper: '0x420000000000000000000000000000000000000B',
OVM_GasPriceOracle: '0x420000000000000000000000000000000000000F',
ERC1820Registry: '0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24', ERC1820Registry: '0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24',
} }
...@@ -137,9 +137,11 @@ export const makeStateDump = async (cfg: RollupDeployConfig): Promise<any> => { ...@@ -137,9 +137,11 @@ export const makeStateDump = async (cfg: RollupDeployConfig): Promise<any> => {
'OVM_StateManager', 'OVM_StateManager',
'OVM_ETH', 'OVM_ETH',
'OVM_ExecutionManagerWrapper', 'OVM_ExecutionManagerWrapper',
'OVM_GasPriceOracle',
], ],
deployOverrides: {}, deployOverrides: {},
waitForReceipts: false, waitForReceipts: false,
gasPriceOracleOwner: cfg.gasPriceOracleOwner,
} }
config = { ...config, ...cfg } config = { ...config, ...cfg }
...@@ -154,6 +156,7 @@ export const makeStateDump = async (cfg: RollupDeployConfig): Promise<any> => { ...@@ -154,6 +156,7 @@ export const makeStateDump = async (cfg: RollupDeployConfig): Promise<any> => {
'OVM_ECDSAContractAccount', 'OVM_ECDSAContractAccount',
'OVM_ProxyEOA', 'OVM_ProxyEOA',
'OVM_ExecutionManagerWrapper', 'OVM_ExecutionManagerWrapper',
'OVM_GasPriceOracle',
] ]
const deploymentResult = await deploy(config) const deploymentResult = await deploy(config)
......
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)
)
})
})
})
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