Commit c74f75b3 authored by smartcontracts's avatar smartcontracts Committed by GitHub

maint(ct): clean up deposit gas spec tests (#2460)

Cleans up the deposit gas spec tests using the same techniques as found
in #2458 and #2459.
Co-authored-by: default avatarmergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent dbd38d0d
/* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract } from 'ethers' import { Contract } from 'ethers'
import { MockContract, smock } from '@defi-wonderland/smock' import { MockContract, smock } from '@defi-wonderland/smock'
import { expectApprox } from '@eth-optimism/core-utils' import { expectApprox } from '@eth-optimism/core-utils'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
/* Internal Imports */
import { import {
makeAddressManager, deploy,
L2_GAS_DISCOUNT_DIVISOR, L2_GAS_DISCOUNT_DIVISOR,
ENQUEUE_GAS_COST, ENQUEUE_GAS_COST,
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS,
...@@ -22,44 +21,34 @@ const INITIAL_TOTAL_L1_SUPPLY = 5000 ...@@ -22,44 +21,34 @@ const INITIAL_TOTAL_L1_SUPPLY = 5000
const FINALIZATION_GAS = 1_200_000 const FINALIZATION_GAS = 1_200_000
describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ]', () => { describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ]', () => {
let sequencer: Signer let sequencer: SignerWithAddress
let alice: Signer let alice: SignerWithAddress
before(async () => { before(async () => {
;[sequencer, alice] = await ethers.getSigners() ;[sequencer, alice] = await ethers.getSigners()
}) })
let AddressManager: Contract let AddressManager: Contract
before('Deploy address manager and register sequencer', async () => { let CanonicalTransactionChain: Contract
AddressManager = await makeAddressManager() before(async () => {
AddressManager = await deploy('Lib_AddressManager')
CanonicalTransactionChain = await deploy('CanonicalTransactionChain', {
args: [
AddressManager.address,
MAX_GAS_LIMIT,
L2_GAS_DISCOUNT_DIVISOR,
ENQUEUE_GAS_COST,
],
})
const batches = await deploy('ChainStorageContainer', {
args: [AddressManager.address, 'CanonicalTransactionChain'],
})
await AddressManager.setAddress( await AddressManager.setAddress(
'OVM_Sequencer', 'OVM_Sequencer',
await sequencer.getAddress() await sequencer.getAddress()
) )
})
let CanonicalTransactionChain: Contract
let Factory__ChainStorageContainer: ContractFactory
before('Init CTC and Storage Container contracts.', async () => {
CanonicalTransactionChain = await (
await ethers.getContractFactory('CanonicalTransactionChain')
).deploy(
AddressManager.address,
MAX_GAS_LIMIT,
L2_GAS_DISCOUNT_DIVISOR,
ENQUEUE_GAS_COST
)
Factory__ChainStorageContainer = await ethers.getContractFactory(
'ChainStorageContainer'
)
const batches = await Factory__ChainStorageContainer.deploy(
AddressManager.address,
'CanonicalTransactionChain'
)
await Factory__ChainStorageContainer.deploy(
AddressManager.address,
'CanonicalTransactionChain'
)
await AddressManager.setAddress( await AddressManager.setAddress(
'ChainStorageContainer-CTC-batches', 'ChainStorageContainer-CTC-batches',
...@@ -72,50 +61,43 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ...@@ -72,50 +61,43 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage
) )
}) })
// 3 Messenger
let L1CrossDomainMessenger: Contract let L1CrossDomainMessenger: Contract
before('Deploy Messenger proxy and implementation', async () => { before(async () => {
// Deploy the implementation contract first const xDomainMessengerImpl = await deploy('L1CrossDomainMessenger')
const xDomainMessengerImpl = await (
await ethers.getContractFactory('L1CrossDomainMessenger')
).deploy()
await AddressManager.setAddress( await AddressManager.setAddress(
'L1CrossDomainMessenger', 'L1CrossDomainMessenger',
xDomainMessengerImpl.address xDomainMessengerImpl.address
) )
// Deploy and initialize the Proxy Messenger
const proxy = await ( const proxy = await deploy('Lib_ResolvedDelegateProxy', {
await ethers.getContractFactory('Lib_ResolvedDelegateProxy') args: [AddressManager.address, 'L1CrossDomainMessenger'],
).deploy(AddressManager.address, 'L1CrossDomainMessenger') })
L1CrossDomainMessenger = xDomainMessengerImpl.attach(proxy.address) L1CrossDomainMessenger = xDomainMessengerImpl.attach(proxy.address)
await L1CrossDomainMessenger.initialize(AddressManager.address) await L1CrossDomainMessenger.initialize(AddressManager.address)
}) })
// 4 Bridge
let L1ERC20: MockContract<Contract> let L1ERC20: MockContract<Contract>
let L1StandardBridge: Contract let L1StandardBridge: Contract
before('Deploy the bridge and setup the token', async () => { before('Deploy the bridge and setup the token', async () => {
// Deploy the Bridge L1StandardBridge = await deploy('L1StandardBridge')
L1StandardBridge = await (
await ethers.getContractFactory('L1StandardBridge')
).deploy()
await L1StandardBridge.initialize( await L1StandardBridge.initialize(
L1CrossDomainMessenger.address, L1CrossDomainMessenger.address,
NON_ZERO_ADDRESS NON_ZERO_ADDRESS
) )
L1ERC20 = await ( L1ERC20 = await (await smock.mock('ERC20')).deploy('L1ERC20', 'ERC')
await smock.mock('@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20')
).deploy('L1ERC20', 'ERC')
const aliceAddress = await alice.getAddress()
await L1ERC20.setVariable('_totalSupply', INITIAL_TOTAL_L1_SUPPLY) await L1ERC20.setVariable('_totalSupply', INITIAL_TOTAL_L1_SUPPLY)
await L1ERC20.setVariable('_balances', { await L1ERC20.setVariable('_balances', {
[aliceAddress]: INITIAL_TOTAL_L1_SUPPLY, [alice.address]: INITIAL_TOTAL_L1_SUPPLY,
}) })
}) })
describe('[GAS BENCHMARK] L1 to L2 Deposit costs [ @skip-on-coverage ]', async () => { describe('[GAS BENCHMARK] L1 to L2 Deposit costs [ @skip-on-coverage ]', async () => {
const depositAmount = 1_000 const depositAmount = 1_000
before(async () => { before(async () => {
// Load a transaction into the queue first to 'dirty' the buffer's length slot // Load a transaction into the queue first to 'dirty' the buffer's length slot
await CanonicalTransactionChain.enqueue( await CanonicalTransactionChain.enqueue(
...@@ -124,6 +106,7 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ...@@ -124,6 +106,7 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage
'0x1234' '0x1234'
) )
}) })
it('cost to deposit ETH', async () => { it('cost to deposit ETH', async () => {
// Alice calls deposit on the bridge and the L1 bridge calls transferFrom on the token. // Alice calls deposit on the bridge and the L1 bridge calls transferFrom on the token.
const res = await L1StandardBridge.connect(alice).depositETH( const res = await L1StandardBridge.connect(alice).depositETH(
...@@ -137,12 +120,14 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ...@@ -137,12 +120,14 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage
const receipt = await res.wait() const receipt = await res.wait()
const gasUsed = receipt.gasUsed.toNumber() const gasUsed = receipt.gasUsed.toNumber()
console.log(' - Gas used:', gasUsed) console.log(' - Gas used:', gasUsed)
expectApprox(gasUsed, 132_481, { expectApprox(gasUsed, 132_481, {
absoluteUpperDeviation: 500, absoluteUpperDeviation: 500,
// Assert a lower bound of 1% reduction on gas cost. If your tests are breaking because your // Assert a lower bound of 1% reduction on gas cost. If your tests are breaking because your
// contracts are too efficient, consider updating the target value! // contracts are too efficient, consider updating the target value!
percentLowerDeviation: 1, percentLowerDeviation: 1,
}) })
// Sanity check that the message was enqueued. // Sanity check that the message was enqueued.
expect(await CanonicalTransactionChain.getQueueLength()).to.equal(2) expect(await CanonicalTransactionChain.getQueueLength()).to.equal(2)
}) })
...@@ -152,6 +137,7 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ...@@ -152,6 +137,7 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage
L1StandardBridge.address, L1StandardBridge.address,
depositAmount depositAmount
) )
// Alice calls deposit on the bridge and the L1 bridge calls transferFrom on the token. // Alice calls deposit on the bridge and the L1 bridge calls transferFrom on the token.
const res = await L1StandardBridge.connect(alice).depositERC20( const res = await L1StandardBridge.connect(alice).depositERC20(
L1ERC20.address, L1ERC20.address,
...@@ -160,9 +146,11 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ...@@ -160,9 +146,11 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage
FINALIZATION_GAS, FINALIZATION_GAS,
NON_NULL_BYTES32 NON_NULL_BYTES32
) )
const receipt = await res.wait() const receipt = await res.wait()
const gasUsed = receipt.gasUsed.toNumber() const gasUsed = receipt.gasUsed.toNumber()
console.log(' - Gas used:', gasUsed) console.log(' - Gas used:', gasUsed)
expectApprox(gasUsed, 192_822, { expectApprox(gasUsed, 192_822, {
absoluteUpperDeviation: 500, absoluteUpperDeviation: 500,
// Assert a lower bound of 1% reduction on gas cost. If your tests are breaking because your // Assert a lower bound of 1% reduction on gas cost. If your tests are breaking because your
......
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