Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 9 additions & 0 deletions contracts/gateway/GraphTokenGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ abstract contract GraphTokenGateway is GraphUpgradeable, Pausable, Managed, ITok
* @param _newPaused New value for the pause state (true means the transfers will be paused)
*/
function setPaused(bool _newPaused) external onlyGovernorOrGuardian {
if (!_newPaused) {
_checksBeforeUnpause();
}
_setPaused(_newPaused);
}

Expand All @@ -54,4 +57,10 @@ abstract contract GraphTokenGateway is GraphUpgradeable, Pausable, Managed, ITok
function paused() external view returns (bool) {
return _paused;
}

/**
* @dev Runs state validation before unpausing, reverts if
* something is not set properly
*/
function _checksBeforeUnpause() internal view virtual;
}
11 changes: 11 additions & 0 deletions contracts/gateway/L1GraphTokenGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -356,4 +356,15 @@ contract L1GraphTokenGateway is GraphTokenGateway, L1ArbitrumMessenger {
}
return l2GRT;
}

/**
* @dev Runs state validation before unpausing, reverts if
* something is not set properly
*/
function _checksBeforeUnpause() internal view override {
require(inbox != address(0), "INBOX_NOT_SET");
require(l1Router != address(0), "ROUTER_NOT_SET");
require(l2Counterpart != address(0), "L2_COUNTERPART_NOT_SET");
require(escrow != address(0), "ESCROW_NOT_SET");
}
}
10 changes: 10 additions & 0 deletions contracts/l2/gateway/L2GraphTokenGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,14 @@ contract L2GraphTokenGateway is GraphTokenGateway, L2ArbitrumMessenger, Reentran
}
return (from, extraData);
}

/**
* @dev Runs state validation before unpausing, reverts if
* something is not set properly
*/
function _checksBeforeUnpause() internal view override {
require(l2Router != address(0), "ROUTER_NOT_SET");
require(l1Counterpart != address(0), "L1_COUNTERPART_NOT_SET");
require(l1GRT != address(0), "L1GRT_NOT_SET");
}
}
46 changes: 38 additions & 8 deletions test/gateway/l1GraphTokenGateway.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,35 @@ describe('L1GraphTokenGateway', () => {
tx = l1GraphTokenGateway.connect(tokenSender.signer).setPaused(true)
await expect(tx).revertedWith('Only Governor or Guardian can call')
})
it('can be paused and unpaused by the governor', async function () {
it('cannot be unpaused if some state variables are not set', async function () {
let tx = l1GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).emit(l1GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l1GraphTokenGateway.paused()).eq(false)
tx = l1GraphTokenGateway.connect(governor.signer).setPaused(true)
await expect(tx).revertedWith('INBOX_NOT_SET')
await l1GraphTokenGateway
.connect(governor.signer)
.setArbitrumAddresses(arbitrumMocks.inboxMock.address, mockRouter.address)
tx = l1GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).revertedWith('L2_COUNTERPART_NOT_SET')
await l1GraphTokenGateway
.connect(governor.signer)
.setL2CounterpartAddress(mockL2Gateway.address)
tx = l1GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).revertedWith('ESCROW_NOT_SET')
})
it('can be paused and unpaused by the governor', async function () {
await fixture.configureL1Bridge(
governor.signer,
arbitrumMocks,
fixtureContracts,
mockRouter.address,
mockL2GRT.address,
mockL2Gateway.address,
)
let tx = l1GraphTokenGateway.connect(governor.signer).setPaused(true)
await expect(tx).emit(l1GraphTokenGateway, 'PauseChanged').withArgs(true)
await expect(await l1GraphTokenGateway.paused()).eq(true)
tx = l1GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).emit(l1GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l1GraphTokenGateway.paused()).eq(false)
})
describe('setPauseGuardian', function () {
it('cannot be called by someone other than governor', async function () {
Expand All @@ -261,13 +283,21 @@ describe('L1GraphTokenGateway', () => {
.withArgs(AddressZero, pauseGuardian.address)
})
it('allows a pause guardian to pause and unpause', async function () {
await fixture.configureL1Bridge(
governor.signer,
arbitrumMocks,
fixtureContracts,
mockRouter.address,
mockL2GRT.address,
mockL2Gateway.address,
)
await l1GraphTokenGateway.connect(governor.signer).setPauseGuardian(pauseGuardian.address)
let tx = l1GraphTokenGateway.connect(pauseGuardian.signer).setPaused(false)
await expect(tx).emit(l1GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l1GraphTokenGateway.paused()).eq(false)
tx = l1GraphTokenGateway.connect(pauseGuardian.signer).setPaused(true)
let tx = l1GraphTokenGateway.connect(pauseGuardian.signer).setPaused(true)
await expect(tx).emit(l1GraphTokenGateway, 'PauseChanged').withArgs(true)
await expect(await l1GraphTokenGateway.paused()).eq(true)
tx = l1GraphTokenGateway.connect(pauseGuardian.signer).setPaused(false)
await expect(tx).emit(l1GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l1GraphTokenGateway.paused()).eq(false)
})
})
})
Expand Down
42 changes: 34 additions & 8 deletions test/l2/l2GraphTokenGateway.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,32 @@ describe('L2GraphTokenGateway', () => {
tx = l2GraphTokenGateway.connect(tokenSender.signer).setPaused(true)
await expect(tx).revertedWith('Only Governor or Guardian can call')
})
it('can be paused and unpaused by the governor', async function () {
it('cannot be paused if some state variables are not set', async function () {
let tx = l2GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).emit(l2GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l2GraphTokenGateway.paused()).eq(false)
tx = l2GraphTokenGateway.connect(governor.signer).setPaused(true)
await expect(tx).revertedWith('ROUTER_NOT_SET')
await l2GraphTokenGateway.connect(governor.signer).setL2Router(mockRouter.address)
tx = l2GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).revertedWith('L1_COUNTERPART_NOT_SET')
await l2GraphTokenGateway
.connect(governor.signer)
.setL1CounterpartAddress(mockL1Gateway.address)
tx = l2GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).revertedWith('L1GRT_NOT_SET')
})
it('can be paused and unpaused by the governor', async function () {
await fixture.configureL2Bridge(
governor.signer,
fixtureContracts,
mockRouter.address,
mockL1GRT.address,
mockL1Gateway.address,
)
let tx = l2GraphTokenGateway.connect(governor.signer).setPaused(true)
await expect(tx).emit(l2GraphTokenGateway, 'PauseChanged').withArgs(true)
await expect(await l2GraphTokenGateway.paused()).eq(true)
tx = l2GraphTokenGateway.connect(governor.signer).setPaused(false)
await expect(tx).emit(l2GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l2GraphTokenGateway.paused()).eq(false)
})
describe('setPauseGuardian', function () {
it('cannot be called by someone other than governor', async function () {
Expand All @@ -197,13 +216,20 @@ describe('L2GraphTokenGateway', () => {
.withArgs(AddressZero, pauseGuardian.address)
})
it('allows a pause guardian to pause and unpause', async function () {
await fixture.configureL2Bridge(
governor.signer,
fixtureContracts,
mockRouter.address,
mockL1GRT.address,
mockL1Gateway.address,
)
await l2GraphTokenGateway.connect(governor.signer).setPauseGuardian(pauseGuardian.address)
let tx = l2GraphTokenGateway.connect(pauseGuardian.signer).setPaused(false)
await expect(tx).emit(l2GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l2GraphTokenGateway.paused()).eq(false)
tx = l2GraphTokenGateway.connect(pauseGuardian.signer).setPaused(true)
let tx = l2GraphTokenGateway.connect(pauseGuardian.signer).setPaused(true)
await expect(tx).emit(l2GraphTokenGateway, 'PauseChanged').withArgs(true)
await expect(await l2GraphTokenGateway.paused()).eq(true)
tx = l2GraphTokenGateway.connect(pauseGuardian.signer).setPaused(false)
await expect(tx).emit(l2GraphTokenGateway, 'PauseChanged').withArgs(false)
await expect(await l2GraphTokenGateway.paused()).eq(false)
})
})
})
Expand Down