The home for Hyperlane core contracts, sdk packages, and other infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
hyperlane-monorepo/solidity/test/interchainGasPaymaster.test.ts

142 lines
4.1 KiB

import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
import { expect } from 'chai';
import { BigNumber } from 'ethers';
import { ethers } from 'hardhat';
import {
InterchainGasPaymaster,
InterchainGasPaymaster__factory,
} from '../types';
const MESSAGE_ID =
'0x6ae9a99190641b9ed0c07143340612dde0e9cb7deaa5fe07597858ae9ba5fd7f';
const DESTINATION_DOMAIN = 1234;
const GAS_PAYMENT_AMOUNT = 123456789;
const GAS_AMOUNT = 4444;
const REFUND_ADDRESS = '0xc0ffee0000000000000000000000000000000000';
const OWNER = '0xdeadbeef00000000000000000000000000000000';
describe('InterchainGasPaymaster', async () => {
let paymaster: InterchainGasPaymaster, signer: SignerWithAddress;
before(async () => {
[signer] = await ethers.getSigners();
});
beforeEach(async () => {
const paymasterFactory = new InterchainGasPaymaster__factory(signer);
paymaster = await paymasterFactory.deploy();
});
describe('#initialize', () => {
it('should not be callable twice', async () => {
await expect(paymaster.initialize()).to.be.reverted;
});
});
describe('#payForGas', () => {
it('deposits the required amount into the contract', async () => {
const refundAddressBalanceBefore = await signer.provider!.getBalance(
REFUND_ADDRESS,
);
const paymasterBalanceBefore = await signer.provider!.getBalance(
paymaster.address,
);
await paymaster.payForGas(
MESSAGE_ID,
DESTINATION_DOMAIN,
GAS_AMOUNT,
REFUND_ADDRESS,
{
value: GAS_PAYMENT_AMOUNT,
},
);
const requiredPayment = await paymaster.quoteGasPayment(
DESTINATION_DOMAIN,
GAS_AMOUNT,
);
const paymasterBalanceAfter = await signer.provider!.getBalance(
paymaster.address,
);
expect(paymasterBalanceAfter.sub(paymasterBalanceBefore)).equals(
requiredPayment,
);
// Ensure that any overpayment was refunded to the refund address
const refundAddressBalanceAfter = await signer.provider!.getBalance(
REFUND_ADDRESS,
);
expect(refundAddressBalanceAfter.sub(refundAddressBalanceBefore)).equals(
BigNumber.from(GAS_PAYMENT_AMOUNT).sub(requiredPayment),
);
});
it('emits the GasPayment event', async () => {
await expect(
paymaster.payForGas(
MESSAGE_ID,
DESTINATION_DOMAIN,
GAS_AMOUNT,
REFUND_ADDRESS,
{
value: GAS_PAYMENT_AMOUNT,
},
),
)
.to.emit(paymaster, 'GasPayment')
.withArgs(MESSAGE_ID, GAS_AMOUNT, GAS_PAYMENT_AMOUNT);
});
});
describe('#quoteGasPayment', () => {
it('returns 1 wei', async () => {
const quotedPayment = await paymaster.quoteGasPayment(
DESTINATION_DOMAIN,
GAS_AMOUNT,
);
expect(quotedPayment).equals(1);
});
});
describe('#claim', () => {
it('sends the entire balance of the contract to the owner', async () => {
// First pay some ether into the contract
await paymaster.payForGas(
MESSAGE_ID,
DESTINATION_DOMAIN,
GAS_AMOUNT,
REFUND_ADDRESS,
{
value: GAS_PAYMENT_AMOUNT,
},
);
const requiredPayment = await paymaster.quoteGasPayment(
DESTINATION_DOMAIN,
GAS_AMOUNT,
);
// Set the owner to a different address so we aren't paying gas with the same
// address we want to observe the balance of
await paymaster.transferOwnership(OWNER);
const ownerBalanceBefore = await signer.provider!.getBalance(OWNER);
expect(ownerBalanceBefore).equals(0);
const paymasterBalanceBefore = await signer.provider!.getBalance(
paymaster.address,
);
expect(paymasterBalanceBefore).equals(requiredPayment);
await paymaster.claim();
const ownerBalanceAfter = await signer.provider!.getBalance(OWNER);
expect(ownerBalanceAfter).equals(requiredPayment);
const paymasterBalanceAfter = await signer.provider!.getBalance(
paymaster.address,
);
expect(paymasterBalanceAfter).equals(0);
});
});
});