liquid-funding/contracts/EscapableApp.sol

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);
}
}