-
Notifications
You must be signed in to change notification settings - Fork 212
/
Copy pathVault.sol
108 lines (91 loc) · 3.91 KB
/
Vault.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
pragma solidity 0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/common/DepositableStorage.sol";
import "@aragon/os/contracts/common/EtherTokenConstant.sol";
import "@aragon/os/contracts/common/SafeERC20.sol";
import "@aragon/os/contracts/lib/token/ERC20.sol";
contract Vault is EtherTokenConstant, AragonApp, DepositableStorage {
using SafeERC20 for ERC20;
bytes32 public constant TRANSFER_ROLE = keccak256("TRANSFER_ROLE");
string private constant ERROR_DATA_NON_ZERO = "VAULT_DATA_NON_ZERO";
string private constant ERROR_NOT_DEPOSITABLE = "VAULT_NOT_DEPOSITABLE";
string private constant ERROR_DEPOSIT_VALUE_ZERO = "VAULT_DEPOSIT_VALUE_ZERO";
string private constant ERROR_TRANSFER_VALUE_ZERO = "VAULT_TRANSFER_VALUE_ZERO";
string private constant ERROR_SEND_REVERTED = "VAULT_SEND_REVERTED";
string private constant ERROR_VALUE_MISMATCH = "VAULT_VALUE_MISMATCH";
string private constant ERROR_TOKEN_TRANSFER_FROM_REVERTED = "VAULT_TOKEN_TRANSFER_FROM_REVERT";
string private constant ERROR_TOKEN_TRANSFER_REVERTED = "VAULT_TOKEN_TRANSFER_REVERTED";
event VaultTransfer(address indexed token, address indexed to, uint256 amount);
event VaultDeposit(address indexed token, address indexed sender, uint256 amount);
/**
* @dev On a normal send() or transfer() this fallback is never executed as it will be
* intercepted by the Proxy (see aragonOS#281)
*/
function () external payable isInitialized {
require(msg.data.length == 0, ERROR_DATA_NON_ZERO);
_deposit(ETH, msg.value);
}
/**
* @notice Initialize Vault app
* @dev As an AragonApp it needs to be initialized in order for roles (`auth` and `authP`) to work
*/
function initialize() external onlyInit {
initialized();
setDepositable(true);
}
/**
* @notice Deposit `_value` `_token` to the vault
* @param _token Address of the token being transferred
* @param _value Amount of tokens being transferred
*/
function deposit(address _token, uint256 _value) external payable isInitialized {
_deposit(_token, _value);
}
/**
* @notice Transfer `_value` `_token` from the Vault to `_to`
* @param _token Address of the token being transferred
* @param _to Address of the recipient of tokens
* @param _value Amount of tokens being transferred
*/
/* solium-disable-next-line function-order */
function transfer(address _token, address _to, uint256 _value)
external
authP(TRANSFER_ROLE, arr(_token, _to, _value))
{
require(_value > 0, ERROR_TRANSFER_VALUE_ZERO);
if (_token == ETH) {
require(_to.send(_value), ERROR_SEND_REVERTED);
} else {
require(ERC20(_token).safeTransfer(_to, _value), ERROR_TOKEN_TRANSFER_REVERTED);
}
emit VaultTransfer(_token, _to, _value);
}
function balance(address _token) public view returns (uint256) {
if (_token == ETH) {
return address(this).balance;
} else {
return ERC20(_token).staticBalanceOf(address(this));
}
}
/**
* @dev Disable recovery escape hatch, as it could be used
* maliciously to transfer funds away from the vault
*/
function allowRecoverability(address) public view returns (bool) {
return false;
}
function _deposit(address _token, uint256 _value) internal {
require(isDepositable(), ERROR_NOT_DEPOSITABLE);
require(_value > 0, ERROR_DEPOSIT_VALUE_ZERO);
if (_token == ETH) {
// Deposit is implicit in this case
require(msg.value == _value, ERROR_VALUE_MISMATCH);
} else {
require(
ERC20(_token).safeTransferFrom(msg.sender, address(this), _value),
ERROR_TOKEN_TRANSFER_FROM_REVERTED
);
}
emit VaultDeposit(_token, msg.sender, _value);
}
}