-
Notifications
You must be signed in to change notification settings - Fork 375
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow a specified address to disable/enable the Exchange (#1467)
- Loading branch information
1 parent
d8d97af
commit 82aac04
Showing
7 changed files
with
182 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
pragma solidity ^0.5.3; | ||
|
||
|
||
contract Freezable { | ||
bool public frozen; | ||
address public freezer; | ||
|
||
// onlyFreezer functions can only be called by the specified `freezer` address | ||
modifier onlyFreezer() { | ||
require(msg.sender == freezer); | ||
_; | ||
} | ||
|
||
// onlyWhenNotFrozen functions can only be called when `frozen` is false, otherwise they will | ||
// revert. | ||
modifier onlyWhenNotFrozen() { | ||
require(!frozen); | ||
_; | ||
} | ||
|
||
/** | ||
* @notice Sets the address that is allowed to freeze/unfreeze the contract. | ||
* @param _freezer The address that is allowed to freeze/unfree the contract | ||
* @dev This function is `internal` and leaves its permissioning up to the inheriting contract. | ||
*/ | ||
function _setFreezer(address _freezer) internal { | ||
freezer = _freezer; | ||
} | ||
|
||
/** | ||
* @notice Freezes the contract, disabling `onlyWhenNotFrozen` functions. | ||
*/ | ||
function freeze() external onlyFreezer { | ||
frozen = true; | ||
} | ||
|
||
/** | ||
* @notice Unreezes the contract, enabling `onlyWhenNotFrozen` functions. | ||
*/ | ||
function unfreeze() external onlyFreezer { | ||
frozen = false; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
packages/protocol/contracts/baklava/test/FreezableTest.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
pragma solidity ^0.5.8; | ||
|
||
import "../Freezable.sol"; | ||
|
||
|
||
contract FreezableTest is Freezable { | ||
event FunctionCalled(); | ||
|
||
function setFreezer(address _freezer) external { | ||
_setFreezer(_freezer); | ||
} | ||
|
||
function freezableFunction() external onlyWhenNotFrozen { | ||
emit FunctionCalled(); | ||
} | ||
|
||
function nonfreezableFunction() external { | ||
emit FunctionCalled(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { assertSameAddress, assertLogMatches2, assertRevert } from '@celo/protocol/lib/test-utils' | ||
import { FreezableTestInstance } from 'types' | ||
|
||
contract('Freezable', (accounts: string[]) => { | ||
const FreezableTest = artifacts.require('FreezableTest') | ||
let freezableTest: FreezableTestInstance | ||
|
||
beforeEach(async () => { | ||
freezableTest = await FreezableTest.new() | ||
freezableTest.setFreezer(accounts[0]) | ||
}) | ||
|
||
describe('_setFreezer', () => { | ||
it('should allow owner to change the freezer', async () => { | ||
// _setFreezer is internal in Freezable, FreezableTest wraps around it with setFreezer | ||
await freezableTest.setFreezer(accounts[1]) | ||
const freezer = await freezableTest.freezer() | ||
assertSameAddress(freezer, accounts[1]) | ||
}) | ||
}) | ||
|
||
describe('when the contract is not frozen', () => { | ||
it('should allow freezable functions to be called', async () => { | ||
const resp = await freezableTest.freezableFunction() | ||
assert.equal(resp.logs.length, 1) | ||
const log = resp.logs[0] | ||
assertLogMatches2(log, { | ||
event: 'FunctionCalled', | ||
args: {}, | ||
}) | ||
}) | ||
|
||
it('should allow non-freezable functions to be called', async () => { | ||
const resp = await freezableTest.nonfreezableFunction() | ||
assert.equal(resp.logs.length, 1) | ||
const log = resp.logs[0] | ||
assertLogMatches2(log, { | ||
event: 'FunctionCalled', | ||
args: {}, | ||
}) | ||
}) | ||
}) | ||
|
||
describe('freeze', () => { | ||
it('should allow freezer to freeze the contract', async () => { | ||
await freezableTest.freeze() | ||
const frozen = await freezableTest.frozen() | ||
assert.isTrue(frozen) | ||
}) | ||
|
||
it('should not allow a non-freezer to freeze the contract', async () => { | ||
await assertRevert(freezableTest.freeze({ from: accounts[1] })) | ||
}) | ||
}) | ||
|
||
describe('unfreeze', () => { | ||
beforeEach(async () => { | ||
freezableTest.freeze() | ||
}) | ||
|
||
it('should allow freezer to unfreeze the contract', async () => { | ||
await freezableTest.unfreeze() | ||
const frozen = await freezableTest.frozen() | ||
assert.isFalse(frozen) | ||
}) | ||
|
||
it('should not allow a non-freezer to unfreeze the contract', async () => { | ||
await assertRevert(freezableTest.freeze({ from: accounts[1] })) | ||
}) | ||
}) | ||
|
||
describe('when the contract is frozen', () => { | ||
beforeEach(async () => { | ||
await freezableTest.freeze() | ||
}) | ||
|
||
it('should revert a freezable function', async () => { | ||
await assertRevert(freezableTest.freezableFunction()) | ||
}) | ||
|
||
it('should not affect a non-freezable function', async () => { | ||
const resp = await freezableTest.nonfreezableFunction() | ||
assert.equal(resp.logs.length, 1) | ||
const log = resp.logs[0] | ||
assertLogMatches2(log, { | ||
event: 'FunctionCalled', | ||
args: {}, | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters