-
Notifications
You must be signed in to change notification settings - Fork 246
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to enable / disable depositable functionality (#401)
- Loading branch information
Showing
20 changed files
with
505 additions
and
144 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
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,19 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "./UnstructuredStorage.sol"; | ||
|
||
|
||
contract DepositableStorage { | ||
using UnstructuredStorage for bytes32; | ||
|
||
// keccak256("aragonOS.depositableStorage.depositable") | ||
bytes32 internal constant DEPOSITABLE_POSITION = 0x665fd576fbbe6f247aff98f5c94a561e3f71ec2d3c988d56f12d342396c50cea; | ||
|
||
function isDepositable() public view returns (bool) { | ||
return DEPOSITABLE_POSITION.getStorageBool(); | ||
} | ||
|
||
function setDepositable(bool _depositable) internal { | ||
DEPOSITABLE_POSITION.setStorageBool(_depositable); | ||
} | ||
} |
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 |
---|---|---|
|
@@ -63,7 +63,7 @@ contract DAOFactory { | |
} | ||
|
||
emit DeployDAO(address(dao)); | ||
|
||
return dao; | ||
} | ||
} |
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 |
---|---|---|
@@ -1,11 +1,17 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../../apps/AragonApp.sol"; | ||
import "../../common/DepositableStorage.sol"; | ||
|
||
|
||
contract AppStubConditionalRecovery is AragonApp { | ||
function allowRecoverability(address token) public view returns (bool) { | ||
// Doesn't allow to recover ether | ||
return token != address(0); | ||
} | ||
contract AppStubConditionalRecovery is AragonApp, DepositableStorage { | ||
function initialize() onlyInit public { | ||
initialized(); | ||
setDepositable(true); | ||
} | ||
|
||
function allowRecoverability(address token) public view returns (bool) { | ||
// Doesn't allow to recover ether | ||
return token != address(0); | ||
} | ||
} |
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,26 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../../apps/AragonApp.sol"; | ||
import "../../apps/UnsafeAragonApp.sol"; | ||
import "../../common/DepositableStorage.sol"; | ||
|
||
|
||
contract AppStubDepositable is AragonApp, DepositableStorage { | ||
function () external payable { | ||
require(isDepositable()); | ||
} | ||
|
||
function initialize() onlyInit public { | ||
initialized(); | ||
} | ||
|
||
function enableDeposits() external { | ||
setDepositable(true); | ||
} | ||
} | ||
|
||
contract UnsafeAppStubDepositable is AppStubDepositable, UnsafeAragonApp { | ||
constructor(IKernel _kernel) public { | ||
setKernel(_kernel); | ||
} | ||
} |
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,14 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../../common/DepositableStorage.sol"; | ||
|
||
|
||
contract DepositableStorageMock is DepositableStorage { | ||
function setDepositableExt(bool _depositable) public { | ||
setDepositable(_depositable); | ||
} | ||
|
||
function getDepositablePosition() public pure returns (bytes32) { | ||
return DEPOSITABLE_POSITION; | ||
} | ||
} |
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,14 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../../common/Initializable.sol"; | ||
|
||
|
||
contract InitializableStorageMock is Initializable { | ||
function initialize() onlyInit public { | ||
initialized(); | ||
} | ||
|
||
function getInitializationBlockPosition() public pure returns (bytes32) { | ||
return INITIALIZATION_BLOCK_POSITION; | ||
} | ||
} |
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,17 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../../common/DepositableStorage.sol"; | ||
import "../../kernel/Kernel.sol"; | ||
|
||
contract KernelDepositableMock is Kernel, DepositableStorage { | ||
constructor(bool _shouldPetrify) Kernel(_shouldPetrify) public { | ||
} | ||
|
||
function () external payable { | ||
require(isDepositable()); | ||
} | ||
|
||
function enableDeposits() external isInitialized { | ||
setDepositable(true); | ||
} | ||
} |
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,119 @@ | ||
const { hash } = require('eth-ens-namehash') | ||
const { assertRevert } = require('./helpers/assertThrow') | ||
const { getBalance } = require('./helpers/web3') | ||
const { onlyIf } = require('./helpers/onlyIf') | ||
|
||
const ACL = artifacts.require('ACL') | ||
const Kernel = artifacts.require('Kernel') | ||
const KernelProxy = artifacts.require('KernelProxy') | ||
const AppProxyUpgradeable = artifacts.require('AppProxyUpgradeable') | ||
const AppProxyPinned = artifacts.require('AppProxyPinned') | ||
|
||
// Mocks | ||
const AppStub = artifacts.require('AppStub') | ||
const UnsafeAppStub = artifacts.require('UnsafeAppStub') | ||
const AppStubDepositable = artifacts.require('AppStubDepositable') | ||
const UnsafeAppStubDepositable = artifacts.require('UnsafeAppStubDepositable') | ||
|
||
const APP_ID = hash('stub.aragonpm.test') | ||
const EMPTY_BYTES = '0x' | ||
const SEND_ETH_GAS = 31000 // 21k base tx cost + 10k limit on depositable proxies | ||
|
||
contract('App funds', accounts => { | ||
let aclBase, kernelBase | ||
let APP_BASES_NAMESPACE | ||
|
||
const permissionsRoot = accounts[0] | ||
|
||
before(async () => { | ||
kernelBase = await Kernel.new(true) // petrify immediately | ||
aclBase = await ACL.new() | ||
|
||
// Setup constants | ||
APP_BASES_NAMESPACE = await kernelBase.APP_BASES_NAMESPACE() | ||
}) | ||
|
||
const appBases = [ | ||
{ | ||
base: AppStub, | ||
unsafeBase: UnsafeAppStub, | ||
}, | ||
{ | ||
base: AppStubDepositable, | ||
unsafeBase: UnsafeAppStubDepositable, | ||
} | ||
] | ||
for ({ base: appBaseType, unsafeBase: unsafeAppBaseType } of appBases) { | ||
context(`> ${appBaseType.contractName}`, () => { | ||
const onlyAppStubDepositable = onlyIf(() => appBaseType === AppStubDepositable) | ||
|
||
// Test the app itself and when it's behind the proxies to make sure their behaviours are the same | ||
const appProxyTypes = ['AppProxyUpgradeable', 'AppProxyPinned'] | ||
for (const appType of ['App', ...appProxyTypes]) { | ||
context(`> ${appType}`, () => { | ||
let appBase, app | ||
|
||
before(async () => { | ||
if (appProxyTypes.includes(appType)) { | ||
// We can reuse the same app base for the proxies | ||
appBase = await appBaseType.new() | ||
} | ||
}) | ||
|
||
beforeEach(async () => { | ||
const kernel = Kernel.at((await KernelProxy.new(kernelBase.address)).address) | ||
await kernel.initialize(aclBase.address, permissionsRoot) | ||
|
||
if (appType === 'App') { | ||
// Use the unsafe version to use directly without a proxy | ||
app = await unsafeAppBaseType.new(kernel.address) | ||
} else { | ||
// Install app | ||
const acl = ACL.at(await kernel.acl()) | ||
const APP_MANAGER_ROLE = await kernelBase.APP_MANAGER_ROLE() | ||
await acl.createPermission(permissionsRoot, kernel.address, APP_MANAGER_ROLE, permissionsRoot) | ||
await kernel.setApp(APP_BASES_NAMESPACE, APP_ID, appBase.address) | ||
|
||
let appProxy | ||
if (appType === 'AppProxyUpgradeable') { | ||
appProxy = await AppProxyUpgradeable.new(kernel.address, APP_ID, EMPTY_BYTES) | ||
} else if (appType === 'AppProxyPinned') { | ||
appProxy = await AppProxyPinned.new(kernel.address, APP_ID, EMPTY_BYTES) | ||
} | ||
|
||
app = appBaseType.at(appProxy.address) | ||
} | ||
|
||
await app.initialize(); | ||
}) | ||
|
||
it('cannot receive ETH', async () => { | ||
assert.isTrue(await app.hasInitialized(), 'should have been initialized') | ||
|
||
await assertRevert(async () => { | ||
await app.sendTransaction({ value: 1, gas: SEND_ETH_GAS }) | ||
}) | ||
}) | ||
|
||
onlyAppStubDepositable(() => { | ||
it('does not have depositing enabled by default', async () => { | ||
assert.isTrue(await app.hasInitialized(), 'should have been initialized') | ||
assert.isFalse(await app.isDepositable(), 'should not be depositable') | ||
}) | ||
|
||
it('can receive ETH after being set to depositable', async () => { | ||
const amount = 1 | ||
const initialBalance = await getBalance(app.address) | ||
|
||
await app.enableDeposits() | ||
assert.isTrue(await app.isDepositable(), 'should be depositable') | ||
|
||
await app.sendTransaction({ value: 1, gas: SEND_ETH_GAS }) | ||
assert.equal((await getBalance(app.address)).valueOf(), initialBalance.plus(amount)) | ||
}) | ||
}) | ||
}) | ||
} | ||
}) | ||
} | ||
}) |
Oops, something went wrong.