///File: ./node_modules/@aragon/os/contracts/acl/IACL.sol pragma solidity ^0.4.18; interface IACL { function initialize(address permissionsCreator) public; function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool); } ///File: ./node_modules/@aragon/os/contracts/common/IVaultRecoverable.sol pragma solidity ^0.4.18; interface IVaultRecoverable { function transferToVault(address token) external; function allowRecoverability(address token) public view returns (bool); function getRecoveryVault() public view returns (address); } ///File: ./node_modules/@aragon/os/contracts/kernel/IKernel.sol pragma solidity ^0.4.18; // This should be an interface, but interfaces can't inherit yet :( contract IKernel is IVaultRecoverable { event SetApp(bytes32 indexed namespace, bytes32 indexed name, bytes32 indexed id, address app); function acl() public view returns (IACL); function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool); function setApp(bytes32 namespace, bytes32 name, address app) public returns (bytes32 id); function getApp(bytes32 id) public view returns (address); } ///File: ./node_modules/@aragon/os/contracts/kernel/KernelStorage.sol pragma solidity 0.4.18; contract KernelConstants { /* bytes32 constant public CORE_NAMESPACE = keccak256("core"); bytes32 constant public APP_BASES_NAMESPACE = keccak256("base"); bytes32 constant public APP_ADDR_NAMESPACE = keccak256("app"); bytes32 constant public KERNEL_APP_ID = apmNamehash("kernel"); bytes32 constant public KERNEL_APP = keccak256(CORE_NAMESPACE, KERNEL_APP_ID); bytes32 constant public ACL_APP_ID = apmNamehash("acl"); bytes32 constant public ACL_APP = keccak256(APP_ADDR_NAMESPACE, ACL_APP_ID); */ bytes32 constant public CORE_NAMESPACE = 0xc681a85306374a5ab27f0bbc385296a54bcd314a1948b6cf61c4ea1bc44bb9f8; bytes32 constant public APP_BASES_NAMESPACE = 0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f; bytes32 constant public APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb; bytes32 constant public ETH_NODE = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae; bytes32 constant public APM_NODE = 0x9065c3e7f7b7ef1ef4e53d2d0b8e0cef02874ab020c1ece79d5f0d3d0111c0ba; bytes32 constant public KERNEL_APP_ID = 0x3b4bf6bf3ad5000ecf0f989d5befde585c6860fea3e574a4fab4c49d1c177d9c; bytes32 constant public KERNEL_APP = 0x2b7d19d0575c228f8d9326801e14149d284dc5bb7b1541c5ad712ae4b2fcaadb; bytes32 constant public ACL_APP_ID = 0xe3262375f45a6e2026b7e7b18c2b807434f2508fe1a2a3dfb493c7df8f4aad6a; bytes32 constant public ACL_APP = 0x4b8e03a458a6ccec5d9077c2490964c1333dd3c72e2db408d7d9a7a36ef5c41a; } contract KernelStorage is KernelConstants { mapping (bytes32 => address) public apps; bytes32 public recoveryVaultId; } ///File: ./node_modules/@aragon/os/contracts/acl/ACLSyntaxSugar.sol pragma solidity ^0.4.18; contract ACLSyntaxSugar { function arr() internal pure returns (uint256[] r) {} function arr(bytes32 _a) internal pure returns (uint256[] r) { return arr(uint256(_a)); } function arr(bytes32 _a, bytes32 _b) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b)); } function arr(address _a) internal pure returns (uint256[] r) { return arr(uint256(_a)); } function arr(address _a, address _b) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b)); } function arr(address _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) { return arr(uint256(_a), _b, _c); } function arr(address _a, uint256 _b) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b)); } function arr(address _a, address _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b), _c, _d, _e); } function arr(address _a, address _b, address _c) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b), uint256(_c)); } function arr(address _a, address _b, uint256 _c) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b), uint256(_c)); } function arr(uint256 _a) internal pure returns (uint256[] r) { r = new uint256[](1); r[0] = _a; } function arr(uint256 _a, uint256 _b) internal pure returns (uint256[] r) { r = new uint256[](2); r[0] = _a; r[1] = _b; } function arr(uint256 _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) { r = new uint256[](3); r[0] = _a; r[1] = _b; r[2] = _c; } function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) { r = new uint256[](4); r[0] = _a; r[1] = _b; r[2] = _c; r[3] = _d; } function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) { r = new uint256[](5); r[0] = _a; r[1] = _b; r[2] = _c; r[3] = _d; r[4] = _e; } } contract ACLHelpers { function decodeParamOp(uint256 _x) internal pure returns (uint8 b) { return uint8(_x >> (8 * 30)); } function decodeParamId(uint256 _x) internal pure returns (uint8 b) { return uint8(_x >> (8 * 31)); } function decodeParamsList(uint256 _x) internal pure returns (uint32 a, uint32 b, uint32 c) { a = uint32(_x); b = uint32(_x >> (8 * 4)); c = uint32(_x >> (8 * 8)); } } ///File: ./node_modules/@aragon/os/contracts/lib/misc/ERCProxy.sol pragma solidity ^0.4.18; contract ERCProxy { uint256 constant public FORWARDING = 1; uint256 constant public UPGRADEABLE = 2; function proxyType() public pure returns (uint256 proxyTypeId); function implementation() public view returns (address codeAddr); } ///File: ./node_modules/@aragon/os/contracts/apps/AppStorage.sol pragma solidity ^0.4.18; contract AppStorage { IKernel public kernel; bytes32 public appId; address internal pinnedCode; // used by Proxy Pinned uint256 internal initializationBlock; // used by Initializable uint256[95] private storageOffset; // forces App storage to start at after 100 slots uint256 private offset; } ///File: ./node_modules/@aragon/os/contracts/common/Initializable.sol pragma solidity ^0.4.18; contract Initializable is AppStorage { modifier onlyInit { require(initializationBlock == 0); _; } modifier isInitialized { require(initializationBlock > 0); _; } /** * @return Block number in which the contract was initialized */ function getInitializationBlock() public view returns (uint256) { return initializationBlock; } /** * @dev Function to be called by top level contract after initialization has finished. */ function initialized() internal onlyInit { initializationBlock = getBlockNumber(); } /** * @dev Returns the current block number. * Using a function rather than `block.number` allows us to easily mock the block number in * tests. */ function getBlockNumber() internal view returns (uint256) { return block.number; } } ///File: ./node_modules/@aragon/os/contracts/common/IsContract.sol pragma solidity ^0.4.18; contract IsContract { function isContract(address _target) internal view returns (bool) { if (_target == address(0)) { return false; } uint256 size; assembly { size := extcodesize(_target) } return size > 0; } } ///File: ./node_modules/@aragon/os/contracts/common/EtherTokenConstant.sol pragma solidity ^0.4.18; // aragonOS and aragon-apps rely on address(0) to denote native ETH, in // contracts where both tokens and ETH are accepted contract EtherTokenConstant { address constant public ETH = address(0); } ///File: ./node_modules/@aragon/os/contracts/lib/zeppelin/token/ERC20Basic.sol pragma solidity ^0.4.11; /** * @title ERC20Basic * @dev Simpler version of ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/179 */ contract ERC20Basic { function totalSupply() public view returns (uint256); function balanceOf(address who) public constant returns (uint256); function transfer(address to, uint256 value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); } ///File: ./node_modules/@aragon/os/contracts/lib/zeppelin/token/ERC20.sol pragma solidity ^0.4.11; import './ERC20Basic.sol'; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 is ERC20Basic { function allowance(address owner, address spender) public constant returns (uint256); function transferFrom(address from, address to, uint256 value) public returns (bool); function approve(address spender, uint256 value) public returns (bool); event Approval(address indexed owner, address indexed spender, uint256 value); } ///File: ./node_modules/@aragon/os/contracts/common/VaultRecoverable.sol pragma solidity ^0.4.18; contract VaultRecoverable is IVaultRecoverable, EtherTokenConstant, IsContract { /** * @notice Send funds to recovery Vault. This contract should never receive funds, * but in case it does, this function allows one to recover them. * @param _token Token balance to be sent to recovery vault. */ function transferToVault(address _token) external { require(allowRecoverability(_token)); address vault = getRecoveryVault(); require(isContract(vault)); if (_token == ETH) { vault.transfer(this.balance); } else { uint256 amount = ERC20(_token).balanceOf(this); ERC20(_token).transfer(vault, amount); } } /** * @dev By default deriving from AragonApp makes it recoverable * @param token Token address that would be recovered * @return bool whether the app allows the recovery */ function allowRecoverability(address token) public view returns (bool) { return true; } } ///File: ./node_modules/@aragon/os/contracts/common/DelegateProxy.sol pragma solidity 0.4.18; contract DelegateProxy is ERCProxy, IsContract { uint256 constant public FWD_GAS_LIMIT = 10000; /** * @dev Performs a delegatecall and returns whatever the delegatecall returned (entire context execution will return!) * @param _dst Destination address to perform the delegatecall * @param _calldata Calldata for the delegatecall */ function delegatedFwd(address _dst, bytes _calldata) internal { delegatedFwd(_dst, _calldata, 0); } /** * @dev Performs a delegatecall and returns whatever the delegatecall returned (entire context execution will return!) * @param _dst Destination address to perform the delegatecall * @param _calldata Calldata for the delegatecall * @param _minReturnSize Minimum size the call needs to return, if less than that it will revert */ function delegatedFwd(address _dst, bytes _calldata, uint256 _minReturnSize) internal { require(isContract(_dst)); uint256 size; uint256 result; uint256 fwd_gas_limit = FWD_GAS_LIMIT; assembly { result := delegatecall(sub(gas, fwd_gas_limit), _dst, add(_calldata, 0x20), mload(_calldata), 0, 0) size := returndatasize } require(size >= _minReturnSize); assembly { let ptr := mload(0x40) returndatacopy(ptr, 0, size) // revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas. // if the call returned error data, forward it switch result case 0 { revert(ptr, size) } default { return(ptr, size) } } } } ///File: ./node_modules/@aragon/os/contracts/common/DepositableDelegateProxy.sol pragma solidity 0.4.18; contract DepositableDelegateProxy is DelegateProxy { event ProxyDeposit(address sender, uint256 value); function () payable public { // send / transfer if (msg.gas < FWD_GAS_LIMIT) { require(msg.value > 0 && msg.data.length == 0); ProxyDeposit(msg.sender, msg.value); } else { // all calls except for send or transfer address target = implementation(); delegatedFwd(target, msg.data); } } } ///File: ./node_modules/@aragon/os/contracts/apps/AppProxyBase.sol pragma solidity 0.4.18; contract AppProxyBase is AppStorage, DepositableDelegateProxy, KernelConstants { /** * @dev Initialize AppProxy * @param _kernel Reference to organization kernel for the app * @param _appId Identifier for app * @param _initializePayload Payload for call to be made after setup to initialize */ function AppProxyBase(IKernel _kernel, bytes32 _appId, bytes _initializePayload) public { kernel = _kernel; appId = _appId; // Implicit check that kernel is actually a Kernel // The EVM doesn't actually provide a way for us to make sure, but we can force a revert to // occur if the kernel is set to 0x0 or a non-code address when we try to call a method on // it. address appCode = getAppBase(appId); // If initialize payload is provided, it will be executed if (_initializePayload.length > 0) { require(isContract(appCode)); // Cannot make delegatecall as a delegateproxy.delegatedFwd as it // returns ending execution context and halts contract deployment require(appCode.delegatecall(_initializePayload)); } } function getAppBase(bytes32 _appId) internal view returns (address) { return kernel.getApp(keccak256(APP_BASES_NAMESPACE, _appId)); } } ///File: ./node_modules/@aragon/os/contracts/apps/AppProxyUpgradeable.sol pragma solidity 0.4.18; contract AppProxyUpgradeable is AppProxyBase { /** * @dev Initialize AppProxyUpgradeable (makes it an upgradeable Aragon app) * @param _kernel Reference to organization kernel for the app * @param _appId Identifier for app * @param _initializePayload Payload for call to be made after setup to initialize */ function AppProxyUpgradeable(IKernel _kernel, bytes32 _appId, bytes _initializePayload) AppProxyBase(_kernel, _appId, _initializePayload) public { } /** * @dev ERC897, the address the proxy would delegate calls to */ function implementation() public view returns (address) { return getAppBase(appId); } /** * @dev ERC897, whether it is a forwarding (1) or an upgradeable (2) proxy */ function proxyType() public pure returns (uint256 proxyTypeId) { return UPGRADEABLE; } } ///File: ./node_modules/@aragon/os/contracts/apps/AppProxyPinned.sol pragma solidity 0.4.18; contract AppProxyPinned is AppProxyBase { /** * @dev Initialize AppProxyPinned (makes it an un-upgradeable Aragon app) * @param _kernel Reference to organization kernel for the app * @param _appId Identifier for app * @param _initializePayload Payload for call to be made after setup to initialize */ function AppProxyPinned(IKernel _kernel, bytes32 _appId, bytes _initializePayload) AppProxyBase(_kernel, _appId, _initializePayload) public { pinnedCode = getAppBase(appId); require(pinnedCode != address(0)); } /** * @dev ERC897, the address the proxy would delegate calls to */ function implementation() public view returns (address) { return pinnedCode; } /** * @dev ERC897, whether it is a forwarding (1) or an upgradeable (2) proxy */ function proxyType() public pure returns (uint256 proxyTypeId) { return FORWARDING; } } ///File: ./node_modules/@aragon/os/contracts/factory/AppProxyFactory.sol pragma solidity 0.4.18; contract AppProxyFactory { event NewAppProxy(address proxy, bool isUpgradeable, bytes32 appId); function newAppProxy(IKernel _kernel, bytes32 _appId) public returns (AppProxyUpgradeable) { return newAppProxy(_kernel, _appId, new bytes(0)); } function newAppProxy(IKernel _kernel, bytes32 _appId, bytes _initializePayload) public returns (AppProxyUpgradeable) { AppProxyUpgradeable proxy = new AppProxyUpgradeable(_kernel, _appId, _initializePayload); NewAppProxy(address(proxy), true, _appId); return proxy; } function newAppProxyPinned(IKernel _kernel, bytes32 _appId) public returns (AppProxyPinned) { return newAppProxyPinned(_kernel, _appId, new bytes(0)); } function newAppProxyPinned(IKernel _kernel, bytes32 _appId, bytes _initializePayload) public returns (AppProxyPinned) { AppProxyPinned proxy = new AppProxyPinned(_kernel, _appId, _initializePayload); NewAppProxy(address(proxy), false, _appId); return proxy; } } ///File: ./node_modules/@aragon/os/contracts/kernel/Kernel.sol pragma solidity 0.4.18; contract Kernel is IKernel, KernelStorage, Initializable, IsContract, AppProxyFactory, ACLSyntaxSugar, VaultRecoverable { // Hardocde constant to save gas //bytes32 constant public APP_MANAGER_ROLE = keccak256("APP_MANAGER_ROLE"); //bytes32 constant public DEFAULT_VAULT_ID = keccak256(APP_ADDR_NAMESPACE, apmNamehash("vault")); bytes32 constant public APP_MANAGER_ROLE = 0xb6d92708f3d4817afc106147d969e229ced5c46e65e0a5002a0d391287762bd0; bytes32 constant public DEFAULT_VAULT_ID = 0x4214e5fd6d0170d69ea641b5614f5093ebecc9928af51e95685c87617489800e; /** * @dev Initialize can only be called once. It saves the block number in which it was initialized. * @notice Initializes a kernel instance along with its ACL and sets `_permissionsCreator` as the entity that can create other permissions * @param _baseAcl Address of base ACL app * @param _permissionsCreator Entity that will be given permission over createPermission */ function initialize(address _baseAcl, address _permissionsCreator) onlyInit public { initialized(); IACL acl = IACL(newAppProxy(this, ACL_APP_ID)); _setApp(APP_BASES_NAMESPACE, ACL_APP_ID, _baseAcl); _setApp(APP_ADDR_NAMESPACE, ACL_APP_ID, acl); acl.initialize(_permissionsCreator); recoveryVaultId = DEFAULT_VAULT_ID; } /** * @dev Create a new instance of an app linked to this kernel * @param _name Name of the app * @param _appBase Address of the app's base implementation * @return AppProxy instance */ function newAppInstance(bytes32 _name, address _appBase) auth(APP_MANAGER_ROLE, arr(APP_BASES_NAMESPACE, _name)) public returns (ERCProxy appProxy) { return newAppInstance(_name, _appBase, false); } /** * @dev Create a new instance of an app linked to this kernel and set its base * implementation if it was not already set * @param _name Name of the app * @param _appBase Address of the app's base implementation * @param _setDefault Whether the app proxy app is the default one. * Useful when the Kernel needs to know of an instance of a particular app, * like Vault for escape hatch mechanism. * @return AppProxy instance */ function newAppInstance(bytes32 _name, address _appBase, bool _setDefault) auth(APP_MANAGER_ROLE, arr(APP_BASES_NAMESPACE, _name)) public returns (ERCProxy appProxy) { _setAppIfNew(APP_BASES_NAMESPACE, _name, _appBase); appProxy = newAppProxy(this, _name); // By calling setApp directly and not the internal functions, we make sure the params are checked // and it will only succeed if sender has permissions to set something to the namespace. if (_setDefault) { setApp(APP_ADDR_NAMESPACE, _name, appProxy); } } /** * @dev Create a new pinned instance of an app linked to this kernel * @param _name Name of the app * @param _appBase Address of the app's base implementation * @return AppProxy instance */ function newPinnedAppInstance(bytes32 _name, address _appBase) auth(APP_MANAGER_ROLE, arr(APP_BASES_NAMESPACE, _name)) public returns (ERCProxy appProxy) { return newPinnedAppInstance(_name, _appBase, false); } /** * @dev Create a new pinned instance of an app linked to this kernel and set * its base implementation if it was not already set * @param _name Name of the app * @param _appBase Address of the app's base implementation * @param _setDefault Whether the app proxy app is the default one. * Useful when the Kernel needs to know of an instance of a particular app, * like Vault for escape hatch mechanism. * @return AppProxy instance */ function newPinnedAppInstance(bytes32 _name, address _appBase, bool _setDefault) auth(APP_MANAGER_ROLE, arr(APP_BASES_NAMESPACE, _name)) public returns (ERCProxy appProxy) { _setAppIfNew(APP_BASES_NAMESPACE, _name, _appBase); appProxy = newAppProxyPinned(this, _name); // By calling setApp directly and not the internal functions, we make sure the params are checked // and it will only succeed if sender has permissions to set something to the namespace. if (_setDefault) { setApp(APP_ADDR_NAMESPACE, _name, appProxy); } } /** * @dev Set the resolving address of an app instance or base implementation * @param _namespace App namespace to use * @param _name Name of the app * @param _app Address of the app * @return ID of app */ function setApp(bytes32 _namespace, bytes32 _name, address _app) auth(APP_MANAGER_ROLE, arr(_namespace, _name)) kernelIntegrity public returns (bytes32 id) { return _setApp(_namespace, _name, _app); } /** * @dev Get the address of an app instance or base implementation * @param _id App identifier * @return Address of the app */ function getApp(bytes32 _id) public view returns (address) { return apps[_id]; } /** * @dev Get the address of the recovery Vault instance (to recover funds) * @return Address of the Vault */ function getRecoveryVault() public view returns (address) { return apps[recoveryVaultId]; } /** * @dev Set the default vault id for the escape hatch mechanism * @param _name Name of the app */ function setRecoveryVaultId(bytes32 _name) auth(APP_MANAGER_ROLE, arr(APP_ADDR_NAMESPACE, _name)) public { recoveryVaultId = keccak256(APP_ADDR_NAMESPACE, _name); } /** * @dev Get the installed ACL app * @return ACL app */ function acl() public view returns (IACL) { return IACL(getApp(ACL_APP)); } /** * @dev Function called by apps to check ACL on kernel or to check permission status * @param _who Sender of the original call * @param _where Address of the app * @param _what Identifier for a group of actions in app * @param _how Extra data for ACL auth * @return boolean indicating whether the ACL allows the role or not */ function hasPermission(address _who, address _where, bytes32 _what, bytes _how) public view returns (bool) { return acl().hasPermission(_who, _where, _what, _how); } function _setApp(bytes32 _namespace, bytes32 _name, address _app) internal returns (bytes32 id) { require(isContract(_app)); id = keccak256(_namespace, _name); apps[id] = _app; SetApp(_namespace, _name, id, _app); } function _setAppIfNew(bytes32 _namespace, bytes32 _name, address _app) internal returns (bytes32 id) { require(isContract(_app)); id = keccak256(_namespace, _name); address app = getApp(id); if (app != address(0)) { require(app == _app); } else { apps[id] = _app; SetApp(_namespace, _name, id, _app); } } modifier auth(bytes32 _role, uint256[] memory params) { bytes memory how; uint256 byteLength = params.length * 32; assembly { how := params // forced casting mstore(how, byteLength) } // Params is invalid from this point fwd require(hasPermission(msg.sender, address(this), _role, how)); _; } modifier kernelIntegrity { _; // After execution check integrity address kernel = getApp(KERNEL_APP); uint256 size; assembly { size := extcodesize(kernel) } require(size > 0); } }