-
Notifications
You must be signed in to change notification settings - Fork 3
/
TokenVault.sol
123 lines (109 loc) · 4.33 KB
/
TokenVault.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.7.3;
import {Ownable} from "oz-contracts/contracts/access/Ownable.sol";
import {SafeMath} from "oz-contracts/contracts/math/SafeMath.sol";
import {IERC20} from "oz-contracts/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "oz-contracts/contracts/token/ERC20/SafeERC20.sol";
/**
* @title TokenVault
* @dev This is a holder contract for Tokens which will be deployed on the base chain (Ethereum).
*
* When a user transfers Tokens from the base to a satellite chain
* Tokens are 'locked' in this vault contract
* and 'bridge-secured' Tokens (xc-tokens) are 'mint' on the satellite chain.
* This vault contract transfers Tokens from the depositor's wallet to itself.
*
* When a user transfers xc-tokens from a satellite chain back to the base chain
* through a chain-bridge instance, xc-tokens are 'burnt' on a satellite chain
* and locked Tokens are 'unlocked' from this vault contract on the base chain.
* The vault contract transfers Tokens from itself to the recipient's wallet.
*
* The vault owner curates a list of bridge-gateways which are allowed to
* lock and unlock tokens.
*
*/
contract TokenVault is Ownable {
using SafeMath for uint256;
using SafeERC20 for IERC20;
event GatewayLocked(
address indexed bridgeGateway,
address indexed token,
address indexed depositor,
uint256 amount
);
event GatewayUnlocked(
address indexed bridgeGateway,
address indexed token,
address indexed recipient,
uint256 amount
);
event GatewayWhitelistUpdated(address indexed bridgeGateway, bool active);
// White-list of trusted bridge gateway contracts
mapping(address => bool) public whitelistedBridgeGateways;
modifier onlyBridgeGateway() {
require(
whitelistedBridgeGateways[msg.sender],
"TokenVault: Bridge gateway not whitelisted"
);
_;
}
/**
* @notice Adds bridge gateway contract address to whitelist.
* @param bridgeGateway The address of the bridge gateway contract.
*/
function addBridgeGateway(address bridgeGateway) external onlyOwner {
require(
!whitelistedBridgeGateways[bridgeGateway],
"TokenVault: Bridge gateway already whitelisted"
);
whitelistedBridgeGateways[bridgeGateway] = true;
emit GatewayWhitelistUpdated(bridgeGateway, true);
}
/**
* @notice Removes bridge gateway contract address from whitelist.
* @param bridgeGateway The address of the bridge gateway contract.
*/
function removeBridgeGateway(address bridgeGateway) external onlyOwner {
require(
whitelistedBridgeGateways[bridgeGateway],
"TokenVault: Bridge gateway not whitelisted"
);
delete whitelistedBridgeGateways[bridgeGateway];
emit GatewayWhitelistUpdated(bridgeGateway, false);
}
/**
* @notice Transfers specified amount from the depositor's wallet and locks it in the gateway contract.
* @param token address of the token to lock.
* @param depositor address of wallet to transfer specified token from
* @param amount amount of tokens to transfer
*/
function lock(
address token,
address depositor,
uint256 amount
) external onlyBridgeGateway {
IERC20(token).safeTransferFrom(depositor, address(this), amount);
emit GatewayLocked(msg.sender, token, depositor, amount);
}
/**
* @notice Unlocks the specified amount from the gateway contract and transfers it to the recipient.
* @param token address of the token to unlock.
* @param recipient address of wallet to transfer specified token to
* @param amount amount of tokens to transfer
*/
function unlock(
address token,
address recipient,
uint256 amount
) external onlyBridgeGateway {
IERC20(token).safeTransfer(recipient, amount);
emit GatewayUnlocked(msg.sender, token, recipient, amount);
}
/**
* @notice Total balance of the specified token, held by this vault.
* @param token address of the token to check.
*/
function totalLocked(address token) external view returns (uint256) {
return IERC20(token).balanceOf(address(this));
}
}