Skip to content
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
186 changes: 166 additions & 20 deletions integration-tests/test/boba-fee-payment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,12 @@ describe('Boba Fee Payment Integration Tests', async () => {
})

it('{tag:boba} should not be able to withdraw fees before the minimum is met', async () => {
await expect(Boba_GasPriceOracle.withdraw()).to.be.rejected
await expect(Boba_GasPriceOracle.withdrawBOBA()).to.be.rejected
})

it('{tag:boba} should be able to withdraw fees back to L1 once the minimum is met', async function () {
const l1FeeWallet = await Boba_GasPriceOracle.l1FeeWallet()
const balanceBefore = await L1Boba.balanceOf(l1FeeWallet)
const feeWallet = await Boba_GasPriceOracle.feeWallet()
const balanceBefore = await L1Boba.balanceOf(feeWallet)
const withdrawalAmount = await Boba_GasPriceOracle.MIN_WITHDRAWAL_AMOUNT()

const l2WalletBalance = await L2Boba.balanceOf(env.l2Wallet.address)
Expand All @@ -446,7 +446,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
const vaultBalance = await L2Boba.balanceOf(Boba_GasPriceOracle.address)

// Submit the withdrawal.
const withdrawTx = await Boba_GasPriceOracle.withdraw({
const withdrawTx = await Boba_GasPriceOracle.withdrawBOBA({
gasPrice: 0,
})

Expand All @@ -456,7 +456,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
await env.waitForXDomainTransaction(withdrawTx)

// Balance difference should be equal to old L2 balance.
const balanceAfter = await L1Boba.balanceOf(l1FeeWallet)
const balanceAfter = await L1Boba.balanceOf(feeWallet)
expect(balanceAfter.sub(balanceBefore)).to.deep.equal(
BigNumber.from(vaultBalance)
)
Expand Down Expand Up @@ -540,7 +540,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
while (priceRatio < 3000) {
const setPriceRatio = await Boba_GasPriceOracle.connect(
env.l2Wallet_4
).updatePriceRatio(priceRatio)
).updatePriceRatio(priceRatio, priceRatio)
await setPriceRatio.wait()

const ETHBalanceBefore = await env.l2Wallet.getBalance()
Expand Down Expand Up @@ -586,7 +586,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
while (priceRatio < 3000) {
const setPriceRatio = await Boba_GasPriceOracle.connect(
env.l2Wallet_4
).updatePriceRatio(priceRatio)
).updatePriceRatio(priceRatio, priceRatio)
await setPriceRatio.wait()

const ETHBalanceBefore = await env.l2Wallet.getBalance()
Expand Down Expand Up @@ -735,6 +735,12 @@ describe('Boba Fee Payment Integration Tests', async () => {
})
await fundTx.wait()

const fundBobaTx = await L2Boba.transfer(
wallet.address,
ethers.utils.parseEther('10')
)
await fundBobaTx.wait()

// Register the fee token
const registerTx = await Boba_GasPriceOracle.connect(
wallet
Expand Down Expand Up @@ -779,12 +785,31 @@ describe('Boba Fee Payment Integration Tests', async () => {
})
await fundTx.wait()

const fundBobaTx = await L2Boba.transfer(
wallet.address,
ethers.utils.parseEther('10')
)
await fundBobaTx.wait()

// Register the fee token
const registerTx = await Boba_GasPriceOracle.connect(
wallet
).useBobaAsFeeToken()
await registerTx.wait()

const BobaBalance = await L2Boba.balanceOf(wallet.address)
const estimateGas = await L2Boba.connect(wallet).estimateGas.transfer(
env.l2Wallet.address,
BobaBalance
)
const priceRatio = await Boba_GasPriceOracle.priceRatio()
const returnBobaTx = await L2Boba.connect(wallet).transfer(
env.l2Wallet.address,
BobaBalance.sub(estimateGas.mul(priceRatio)),
{ gasLimit: estimateGas }
)
await returnBobaTx.wait()

await expect(
wallet.sendTransaction({
to: env.l2Wallet.address,
Expand All @@ -804,6 +829,12 @@ describe('Boba Fee Payment Integration Tests', async () => {
})
await transferTx.wait()

const fundBobaTx = await L2Boba.transfer(
randomWallet.address,
ethers.utils.parseEther('10')
)
await fundBobaTx.wait()

const registerTx = await Boba_GasPriceOracle.connect(
randomWallet
).useBobaAsFeeToken()
Expand Down Expand Up @@ -840,12 +871,19 @@ describe('Boba Fee Payment Integration Tests', async () => {
name = await L2Boba.name()
version = '1'
chainId = (await env.l2Provider.getNetwork()).chainId

// Add ETH first
await env.l2Wallet.sendTransaction({
to: Boba_GasPriceOracle.address,
value: ethers.utils.parseEther('10'),
})
})

it('{tag:boba} should submit the meta transaction', async () => {
const owner = env.l2Wallet_2.address
const spender = Boba_GasPriceOracle.address
const value = (await Boba_GasPriceOracle.metaTransactionFee()).toString()
const receivedETHAmount = await Boba_GasPriceOracle.receivedETHAmount()
const value = (await Boba_GasPriceOracle.getBOBAForSwap()).toString()
const nonce = (await L2Boba.nonces(env.l2Wallet_2.address)).toNumber()
const deadline = Math.floor(Date.now() / 1000) + 90
const verifyingContract = L2Boba.address
Expand All @@ -865,8 +903,12 @@ describe('Boba Fee Payment Integration Tests', async () => {
const sig = ethers.utils.splitSignature(signature)

const BobaBalanceBefore = await L2Boba.balanceOf(env.l2Wallet_2.address)
const ETHBalanceBefore = await env.l2Wallet_2.getBalance()
const GPO_ETHBalanceBefore = await env.l2Provider.getBalance(
Boba_GasPriceOracle.address
)

await Boba_GasPriceOracle.useBobaAsFeeTokenMetaTransaction(
await Boba_GasPriceOracle.swapBOBAForETHMetaTransaction(
owner,
spender,
value,
Expand All @@ -876,21 +918,27 @@ describe('Boba Fee Payment Integration Tests', async () => {
sig.s
)

const isBobaAsFeeToken = await Boba_GasPriceOracle.bobaFeeTokenUsers(
env.l2Wallet_2.address
)
const BobaBalanceAfter = await L2Boba.balanceOf(env.l2Wallet_2.address)
const ETHBalanceAfter = await env.l2Wallet_2.getBalance()
const GPO_ETHBalanceAfter = await env.l2Provider.getBalance(
Boba_GasPriceOracle.address
)

expect(BobaBalanceAfter).to.be.deep.eq(
BobaBalanceBefore.sub(BigNumber.from(value))
)
expect(isBobaAsFeeToken).to.be.eq(true)
expect(ETHBalanceAfter).to.be.deep.eq(
ETHBalanceBefore.add(receivedETHAmount)
)
expect(GPO_ETHBalanceAfter).to.be.deep.eq(
GPO_ETHBalanceBefore.sub(receivedETHAmount)
)
})

it('{tag:boba} should revert transaction if v, r and s are incorrect', async () => {
const owner = env.l2Wallet_2.address
const spender = Boba_GasPriceOracle.address
const value = (await Boba_GasPriceOracle.metaTransactionFee()).toString()
const value = (await Boba_GasPriceOracle.getBOBAForSwap()).toString()
const nonce = (await L2Boba.nonces(env.l2Wallet_2.address)).toNumber()
const deadline = Math.floor(Date.now() / 1000) + 90
const verifyingContract = Boba_GasPriceOracle.address
Expand All @@ -910,7 +958,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
const sig = ethers.utils.splitSignature(signature)

await expect(
Boba_GasPriceOracle.useBobaAsFeeTokenMetaTransaction(
Boba_GasPriceOracle.swapBOBAForETHMetaTransaction(
owner,
spender,
value,
Expand All @@ -925,7 +973,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
it("{tag:boba} should revert transaction if users don't have sufficient Boba token", async () => {
const owner = env.l2Wallet_2.address
const spender = Boba_GasPriceOracle.address
const value = (await Boba_GasPriceOracle.metaTransactionFee()).toString()
const value = (await Boba_GasPriceOracle.getBOBAForSwap()).toString()
const nonce = (await L2Boba.nonces(env.l2Wallet_2.address)).toNumber()
const deadline = Math.floor(Date.now() / 1000) + 90
const verifyingContract = L2Boba.address
Expand Down Expand Up @@ -959,7 +1007,9 @@ describe('Boba Fee Payment Integration Tests', async () => {
await transferTx.wait()

await expect(
Boba_GasPriceOracle.useBobaAsFeeTokenMetaTransaction(
Boba_GasPriceOracle.connect(
env.l2Wallet_2
).swapBOBAForETHMetaTransaction(
owner,
spender,
value,
Expand All @@ -982,7 +1032,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
it('{tag:boba} should revert transaction if spender is not correct', async () => {
const owner = env.l2Wallet_2.address
const spender = env.addressesBOBA.FeedRegistry
const value = (await Boba_GasPriceOracle.metaTransactionFee()).toString()
const value = (await Boba_GasPriceOracle.getBOBAForSwap()).toString()
const nonce = (await L2Boba.nonces(env.l2Wallet_2.address)).toNumber()
const deadline = Math.floor(Date.now() / 1000) + 90
const verifyingContract = L2Boba.address
Expand All @@ -1002,7 +1052,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
const sig = ethers.utils.splitSignature(signature)

await expect(
Boba_GasPriceOracle.useBobaAsFeeTokenMetaTransaction(
Boba_GasPriceOracle.swapBOBAForETHMetaTransaction(
owner,
spender,
value,
Expand Down Expand Up @@ -1037,7 +1087,7 @@ describe('Boba Fee Payment Integration Tests', async () => {
const sig = ethers.utils.splitSignature(signature)

await expect(
Boba_GasPriceOracle.useBobaAsFeeTokenMetaTransaction(
Boba_GasPriceOracle.swapBOBAForETHMetaTransaction(
owner,
spender,
value,
Expand All @@ -1048,5 +1098,101 @@ describe('Boba Fee Payment Integration Tests', async () => {
)
).to.be.revertedWith('Value is not enough')
})

it('{tag:boba} should swap BOBA for ETH using Boba as the fee token', async () => {
const newWallet = ethers.Wallet.createRandom().connect(env.l2Provider)

// Use Boba as the fee token
await env.l2Wallet.sendTransaction({
to: newWallet.address,
value: ethers.utils.parseEther('1'),
})
await L2Boba.transfer(newWallet.address, ethers.utils.parseEther('100'))
await Boba_GasPriceOracle.connect(newWallet).useBobaAsFeeToken()

// Get BOBA
await L2Boba.transfer(newWallet.address, ethers.utils.parseEther('100'))

// Transfer ETH back
const ETHBalance = await newWallet.getBalance()
await newWallet.sendTransaction({
to: env.l2Wallet.address,
value: ETHBalance,
})

const BobaBalanceBefore = await L2Boba.balanceOf(newWallet.address)
const ETHBalanceBefore = await newWallet.getBalance()
const GPO_ETHBalanceBefore = await env.l2Provider.getBalance(
Boba_GasPriceOracle.address
)

const owner = newWallet.address
const spender = Boba_GasPriceOracle.address
const receivedETHAmount = await Boba_GasPriceOracle.receivedETHAmount()
const value = (await Boba_GasPriceOracle.getBOBAForSwap()).toString()
const nonce = (await L2Boba.nonces(newWallet.address)).toNumber()
const deadline = Math.floor(Date.now() / 1000) + 90
const verifyingContract = L2Boba.address

const data: any = {
primaryType: 'Permit',
types: { EIP712Domain, Permit },
domain: { name, version, chainId, verifyingContract },
message: { owner, spender, value, nonce, deadline },
}

const signature = ethSigUtil.signTypedData(
Buffer.from(newWallet.privateKey.slice(2), 'hex'),
{ data }
)

const sig = ethers.utils.splitSignature(signature)

await Boba_GasPriceOracle.swapBOBAForETHMetaTransaction(
owner,
spender,
value,
deadline,
sig.v,
sig.r,
sig.s
)

const BobaBalanceAfter = await L2Boba.balanceOf(newWallet.address)
const ETHBalanceAfter = await newWallet.getBalance()
const GPO_ETHBalanceAfter = await env.l2Provider.getBalance(
Boba_GasPriceOracle.address
)

expect(BobaBalanceAfter).to.be.deep.eq(
BobaBalanceBefore.sub(BigNumber.from(value))
)
expect(ETHBalanceAfter).to.be.deep.eq(
ETHBalanceBefore.add(receivedETHAmount)
)
expect(GPO_ETHBalanceAfter).to.be.deep.eq(
GPO_ETHBalanceBefore.sub(receivedETHAmount)
)
})

it('{tag:boba} should retrieve ETH', async () => {
const feeWallet = await Boba_GasPriceOracle.feeWallet()
const ETHBalanceBefore = await env.l2Provider.getBalance(feeWallet)
const GPO_ETHBalanceBefore = await env.l2Provider.getBalance(
Boba_GasPriceOracle.address
)

await Boba_GasPriceOracle.connect(env.l2Wallet_4).withdrawETH()

const ETHBalanceAfter = await env.l2Provider.getBalance(feeWallet)
const GPO_ETHBalanceAfter = await env.l2Provider.getBalance(
Boba_GasPriceOracle.address
)

expect(ETHBalanceAfter).to.be.eq(
ETHBalanceBefore.add(GPO_ETHBalanceBefore)
)
expect(GPO_ETHBalanceAfter).to.be.eq(BigNumber.from(0))
})
})
})
Loading