91 lines
3.8 KiB
Solidity
91 lines
3.8 KiB
Solidity
pragma solidity ^0.4.18;
|
|
/*
|
|
Copyright 2016, Jordi Baylina
|
|
Contributor: Adrià Massanet <adria@codecontext.io>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// import "./Owned.sol";
|
|
import "giveth-common-contracts/contracts/ERC20.sol";
|
|
import "@aragon/os/contracts/apps/AragonApp.sol";
|
|
|
|
|
|
/// @dev `EscapableApp` is a base level contract; it creates an escape hatch
|
|
/// function that can be called in an
|
|
/// emergency that will allow designated addresses to send any ether or tokens
|
|
/// held in the contract to an `escapeHatchDestination` as long as they were
|
|
/// not blacklisted
|
|
contract EscapableApp is AragonApp {
|
|
// warning whoever has this role can move all funds to the `escapeHatchDestination`
|
|
bytes32 constant public ESCAPE_HATCH_CALLER_ROLE = keccak256("ESCAPE_HATCH_CALLER_ROLE");
|
|
|
|
event EscapeHatchBlackistedToken(address token);
|
|
event EscapeHatchCalled(address token, uint amount);
|
|
|
|
address public escapeHatchDestination;
|
|
mapping (address=>bool) private escapeBlacklist; // Token contract addresses
|
|
uint[20] private storageOffset; // reserve 20 slots for future upgrades
|
|
|
|
/// @param _escapeHatchDestination The address of a safe location (usu a
|
|
/// Multisig) to send the ether held in this contract; if a neutral address
|
|
/// is required, the WHG Multisig is an option:
|
|
/// 0x8Ff920020c8AD673661c8117f2855C384758C572
|
|
function initialize(address _escapeHatchDestination) onlyInit public {
|
|
initialized();
|
|
require(_escapeHatchDestination != 0x0);
|
|
|
|
escapeHatchDestination = _escapeHatchDestination;
|
|
}
|
|
|
|
/// @notice The `escapeHatch()` should only be called as a last resort if a
|
|
/// security issue is uncovered or something unexpected happened
|
|
/// @param _token to transfer, use 0x0 for ether
|
|
function escapeHatch(address _token) public authP(ESCAPE_HATCH_CALLER_ROLE, arr(_token)) {
|
|
require(escapeBlacklist[_token]==false);
|
|
|
|
uint256 balance;
|
|
|
|
/// @dev Logic for ether
|
|
if (_token == 0x0) {
|
|
balance = this.balance;
|
|
escapeHatchDestination.transfer(balance);
|
|
EscapeHatchCalled(_token, balance);
|
|
return;
|
|
}
|
|
/// @dev Logic for tokens
|
|
ERC20 token = ERC20(_token);
|
|
balance = token.balanceOf(this);
|
|
require(token.transfer(escapeHatchDestination, balance));
|
|
EscapeHatchCalled(_token, balance);
|
|
}
|
|
|
|
/// @notice Checks to see if `_token` is in the blacklist of tokens
|
|
/// @param _token the token address being queried
|
|
/// @return False if `_token` is in the blacklist and can't be taken out of
|
|
/// the contract via the `escapeHatch()`
|
|
function isTokenEscapable(address _token) constant public returns (bool) {
|
|
return !escapeBlacklist[_token];
|
|
}
|
|
|
|
/// @notice Creates the blacklist of tokens that are not able to be taken
|
|
/// out of the contract; can only be done at the deployment, and the logic
|
|
/// to add to the blacklist will be in the constructor of a child contract
|
|
/// @param _token the token contract address that is to be blacklisted
|
|
function _blacklistEscapeToken(address _token) internal {
|
|
escapeBlacklist[_token] = true;
|
|
EscapeHatchBlackistedToken(_token);
|
|
}
|
|
}
|