UNPKG

@hyperlane-xyz/core

Version:

Core solidity contracts for Hyperlane

177 lines (154 loc) 5.43 kB
import { ethers } from 'hardhat' import { publicAbi } from '../test-helpers/helpers' import { assert, expect } from 'chai' import { Contract, ContractFactory } from 'ethers' import { getUsers, Personas } from '../test-helpers/setup' const PERMISSION_NOT_SET = 'PermissionNotSet' let personas: Personas let controllerFactory: ContractFactory let counterFactory: ContractFactory let controller: Contract let counter: Contract before(async () => { personas = (await getUsers()).personas controllerFactory = await ethers.getContractFactory( 'src/v0.8/PermissionedForwardProxy.sol:PermissionedForwardProxy', personas.Carol, ) counterFactory = await ethers.getContractFactory( 'src/v0.8/tests/Counter.sol:Counter', personas.Carol, ) }) describe('PermissionedForwardProxy', () => { beforeEach(async () => { controller = await controllerFactory.connect(personas.Carol).deploy() counter = await counterFactory.connect(personas.Carol).deploy() }) it('has a limited public interface [ @skip-coverage ]', async () => { publicAbi(controller, [ 'forward', 'setPermission', 'removePermission', 'getPermission', // Owned 'acceptOwnership', 'owner', 'transferOwnership', ]) }) describe('#setPermission', () => { describe('when called by a non-owner', () => { it('reverts', async () => { await expect( controller .connect(personas.Eddy) .setPermission( await personas.Carol.getAddress(), await personas.Eddy.getAddress(), ), ).to.be.revertedWith('Only callable by owner') }) }) describe('when called by the owner', () => { it('adds the permission to the proxy', async () => { const tx = await controller .connect(personas.Carol) .setPermission( await personas.Carol.getAddress(), await personas.Eddy.getAddress(), ) const receipt = await tx.wait() const eventLog = receipt?.events assert.equal(eventLog?.length, 1) assert.equal(eventLog?.[0].event, 'PermissionSet') assert.equal(eventLog?.[0].args?.[0], await personas.Carol.getAddress()) assert.equal(eventLog?.[0].args?.[1], await personas.Eddy.getAddress()) expect( await controller.getPermission(await personas.Carol.getAddress()), ).to.be.equal(await personas.Eddy.getAddress()) }) }) }) describe('#removePermission', () => { beforeEach(async () => { // Add permission before testing await controller .connect(personas.Carol) .setPermission( await personas.Carol.getAddress(), await personas.Eddy.getAddress(), ) }) describe('when called by a non-owner', () => { it('reverts', async () => { await expect( controller .connect(personas.Eddy) .removePermission(await personas.Carol.getAddress()), ).to.be.revertedWith('Only callable by owner') }) }) describe('when called by the owner', () => { it('removes the permission to the proxy', async () => { const tx = await controller .connect(personas.Carol) .removePermission(await personas.Carol.getAddress()) const receipt = await tx.wait() const eventLog = receipt?.events assert.equal(eventLog?.length, 1) assert.equal(eventLog?.[0].event, 'PermissionRemoved') assert.equal(eventLog?.[0].args?.[0], await personas.Carol.getAddress()) expect( await controller.getPermission(await personas.Carol.getAddress()), ).to.be.equal(ethers.constants.AddressZero) }) }) }) describe('#forward', () => { describe('when permission does not exist', () => { it('reverts', async () => { await expect( controller .connect(personas.Carol) .forward(await personas.Eddy.getAddress(), '0x'), ).to.be.revertedWithCustomError(controller, PERMISSION_NOT_SET) }) }) describe('when permission exists', () => { beforeEach(async () => { // Add permission before testing await controller .connect(personas.Carol) .setPermission(await personas.Carol.getAddress(), counter.address) }) it('calls target successfully', async () => { await controller .connect(personas.Carol) .forward( counter.address, counter.interface.encodeFunctionData('increment'), ) expect(await counter.count()).to.be.equal(1) }) it('reverts when target reverts and bubbles up error', async () => { await expect( controller .connect(personas.Carol) .forward( counter.address, counter.interface.encodeFunctionData('alwaysRevertWithString'), ), ).to.be.revertedWith('always revert') // Revert strings should be bubbled up await expect( controller .connect(personas.Carol) .forward( counter.address, counter.interface.encodeFunctionData('alwaysRevert'), ), ).to.be.reverted // Javascript VM not able to parse custom errors defined on another contract }) }) }) })