Skip to content
This repository has been archived by the owner on Dec 5, 2021. It is now read-only.

Commit

Permalink
test: fee payments (#40)
Browse files Browse the repository at this point in the history
* fix: use the proxy gateway from the addresses

* test: add fee payment test

* chore: explicitly declare solc version in hardhat config
  • Loading branch information
gakonst authored Apr 8, 2021
1 parent b159f2a commit f7036ed
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 3 deletions.
4 changes: 4 additions & 0 deletions integration-tests/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const config: HardhatUserConfig = {
ovm: true,
},
},
solidity: '0.7.6',
ovm: {
solcVersion: '0.7.6',
},
}

export default config
55 changes: 55 additions & 0 deletions integration-tests/test/fee-payment.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import chai, { expect } from 'chai'
import chaiAsPromised from 'chai-as-promised'
chai.use(chaiAsPromised)
import { BigNumber, Contract, utils } from 'ethers'

import {
l1Provider,
l2Provider,
l1Wallet,
l2Wallet,
getGateway,
getAddressManager,
getOvmEth,
fundUser,
} from './shared/utils'
import { initWatcher } from './shared/watcher-utils'

describe('Fee Payment Integration Tests', async () => {
let OVM_L1ETHGateway: Contract
let OVM_ETH: Contract
let AddressManager: Contract
const other = '0x1234123412341234123412341234123412341234'
const amount = utils.parseEther('1')

before(async () => {
AddressManager = getAddressManager(l1Wallet)
OVM_L1ETHGateway = await getGateway(l1Wallet, AddressManager)
OVM_ETH = getOvmEth(l2Wallet)
const watcher = await initWatcher(l1Provider, l2Provider, AddressManager)
await fundUser(watcher, OVM_L1ETHGateway, amount)
})

it('Paying a nonzero but acceptable gasPrice fee', async () => {
// manually set the gas price because otherwise it's returned as 0
const gasPrice = BigNumber.from(1_000_000)
const amt = amount.div(2)

const balanceBefore = await l2Wallet.getBalance()
const tx = await OVM_ETH.transfer(other, amt, { gasPrice })
await tx.wait()
const balanceAfter = await l2Wallet.getBalance()
expect(balanceBefore.sub(balanceAfter)).to.be.deep.eq(
gasPrice.mul(tx.gasLimit).add(amt)
)
})

it('sequencer rejects transaction with a non-multiple-of-1M gasPrice', async () => {
const gasPrice = BigNumber.from(1_000_000 - 1)
await expect(
OVM_ETH.transfer(other, 0, { gasPrice })
).to.be.eventually.rejectedWith(
'Gas price must be a multiple of 1,000,000 wei'
)
})
})
96 changes: 94 additions & 2 deletions integration-tests/test/shared/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,95 @@
export function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms))
import {
getContractFactory,
getContractInterface,
} from '@eth-optimism/contracts'
import { Watcher } from '@eth-optimism/core-utils'
import {
Contract,
Wallet,
constants,
providers,
BigNumberish,
BigNumber,
} from 'ethers'
import { Direction, waitForXDomainTransaction } from './watcher-utils'

// The hardhat instance
const l1HttpPort = 9545
export const l1Provider = new providers.JsonRpcProvider(
`http://localhost:${l1HttpPort}`
)

const httpPort = 8545
export const l2Provider = new providers.JsonRpcProvider(
`http://localhost:${httpPort}`
)

// The sequencer private key which is funded on L1
export const l1Wallet = new Wallet(
'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
l1Provider
)

// A random private key which should always be funded with deposits from L1 -> L2
// if it's using non-0 gas price
export const l2Wallet = l1Wallet.connect(l2Provider)

// Predeploys
export const PROXY_SEQUENCER_ENTRYPOINT_ADDRESS =
'0x4200000000000000000000000000000000000004'
export const OVM_ETH_ADDRESS = '0x4200000000000000000000000000000000000006'

// The address manager is always at the same address in testnet deployments
export const addressManagerAddress =
'0x5FbDB2315678afecb367f032d93F642f64180aa3'

export const getAddressManager = (provider: any) => {
return getContractFactory('Lib_AddressManager')
.connect(provider)
.attach(addressManagerAddress)
}

// Gets the gateway using the proxy if available
export const getGateway = async (wallet: Wallet, AddressManager: Contract) => {
const l1GatewayInterface = getContractInterface('OVM_L1ETHGateway')
const ProxyGatewayAddress = await AddressManager.getAddress(
'Proxy__OVM_L1ETHGateway'
)
const addressToUse =
ProxyGatewayAddress !== constants.AddressZero
? ProxyGatewayAddress
: await AddressManager.getAddress('OVM_L1ETHGateway')

const OVM_L1ETHGateway = new Contract(
addressToUse,
l1GatewayInterface,
wallet
)

return OVM_L1ETHGateway
}

export const getOvmEth = (wallet: Wallet) => {
const OVM_ETH = new Contract(
OVM_ETH_ADDRESS,
getContractInterface('OVM_ETH'),
wallet
)

return OVM_ETH
}

export const fundUser = async (
watcher: Watcher,
gateway: Contract,
amount: BigNumberish,
recipient?: string
) => {
const value = BigNumber.from(amount)
const tx = recipient
? gateway.depositTo(recipient, { value })
: gateway.deposit({ value })
await waitForXDomainTransaction(watcher, tx, Direction.L1ToL2)
}

export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))
7 changes: 6 additions & 1 deletion ops/scripts/geth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ function envSet() {
# set all the necessary env vars
envSet ETH1_ADDRESS_RESOLVER_ADDRESS AddressManager
envSet ETH1_L1_CROSS_DOMAIN_MESSENGER_ADDRESS Proxy__OVM_L1CrossDomainMessenger
envSet ETH1_L1_ETH_GATEWAY_ADDRESS OVM_L1ETHGateway
envSet ROLLUP_ADDRESS_MANAGER_OWNER_ADDRESS Deployer

# set the address to the proxy gateway if possible
envSet ETH1_L1_ETH_GATEWAY_ADDRESS Proxy__OVM_L1ETHGateway
if [ $ETH1_L1_ETH_GATEWAY_ADDRESS == null ]; then
envSet ETH1_L1_ETH_GATEWAY_ADDRESS OVM_L1ETHGateway
fi

geth --verbosity=6

0 comments on commit f7036ed

Please sign in to comment.