2
2
3
3
pragma solidity ^ 0.8.0 ;
4
4
5
+ import "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
6
+ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol " ;
7
+
5
8
import { RoleStore } from "../role/RoleStore.sol " ;
6
9
import { RoleModule } from "../role/RoleModule.sol " ;
7
10
import { DataStore } from "../data/DataStore.sol " ;
@@ -21,6 +24,8 @@ import { MultichainEventUtils } from "./MultichainEventUtils.sol";
21
24
* @title MultichainHandler
22
25
*/
23
26
contract MultichainHandler is RoleModule , GlobalReentrancyGuard , OracleModule {
27
+ using SafeERC20 for IERC20 ;
28
+
24
29
MultichainVault public multichainVault;
25
30
EventEmitter public eventEmitter;
26
31
ExchangeRouter public exchangeRouter;
@@ -39,7 +44,7 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
39
44
}
40
45
41
46
/**
42
- * Records a deposit from another chain. IMultichainProvider has MULTICHAIN_CONTROLLER role
47
+ * Records a deposit from another chain. IMultichainProvider has CONTROLLER role
43
48
* @param account user address on the source chain
44
49
* @param token address of the token being deposited
45
50
* @param sourceChainId chain id of the source chain
@@ -48,18 +53,30 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
48
53
address account ,
49
54
address token ,
50
55
uint256 sourceChainId
51
- ) external onlyController returns ( address virtualAccount ) {
56
+ ) external onlyController {
52
57
// token should have been transferred to multichainVault by IMultichainProvider
53
58
uint256 amount = multichainVault.recordTransferIn (token);
54
59
if (amount == 0 ) {
55
60
revert Errors.EmptyMultichainDepositAmount ();
56
61
}
57
62
58
- virtualAccount = MultichainUtils. getVirtualAccount ( account, sourceChainId );
63
+ dataStore. incrementUint (Keys. sourceChainBalanceKey (sourceChainId, account, token), amount );
59
64
60
- dataStore.incrementUint (Keys.sourceChainBalanceKey (virtualAccount, token), amount);
65
+ MultichainEventUtils.emitMultichainDeposit (eventEmitter, token, account, amount, sourceChainId);
66
+ }
67
+
68
+ /**
69
+ * @dev transfer the specified amount of tokens from account to receiver
70
+ * @param account the account for which the tokens are subtracted
71
+ * @param token the token to transfer
72
+ * @param receiver the account to transfer to
73
+ * @param amount the amount of tokens to transfer
74
+ */
75
+ function pluginTransfer (address token , address account , address receiver , uint256 amount ) external onlyRouterPlugin { // TODO: confirm access control
76
+ // TODO: tokens should come from MultichainVault and the user's multichain balance should be decreased
77
+ // dataStore.decrementUint(Keys.sourceChainBalanceKey(sourceChainId, account, token), amount);
61
78
62
- MultichainEventUtils. emitMultichainDeposit (eventEmitter, token, virtualAccount, amount, sourceChainId );
79
+ IERC20 (token). safeTransferFrom (account, receiver, amount);
63
80
}
64
81
65
82
/**
@@ -77,12 +94,11 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
77
94
// execute multicall
78
95
exchangeRouter.multicall (multicallArgs);
79
96
80
- address virtualAccount = MultichainUtils.getVirtualAccount (account, sourceChainId);
81
- MultichainEventUtils.emitMultichainMessage (eventEmitter, virtualAccount, sourceChainId);
97
+ MultichainEventUtils.emitMultichainMessage (eventEmitter, account, sourceChainId);
82
98
}
83
99
84
100
/**
85
- * Record a withdrawal to another chain. IMultichainProvider has MULTICHAIN_CONTROLLER role
101
+ * Record a withdrawal to another chain. IMultichainProvider has CONTROLLER role
86
102
* @param account user address on the source chain
87
103
* @param token address of the token being withdrawn
88
104
* @param amount amount of token being withdrawn
@@ -98,8 +114,7 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
98
114
revert Errors.EmptyMultichainWithdrawalAmount ();
99
115
}
100
116
101
- address virtualAccount = MultichainUtils.getVirtualAccount (account, sourceChainId);
102
- bytes32 balanceKey = Keys.sourceChainBalanceKey (virtualAccount, token);
117
+ bytes32 balanceKey = Keys.sourceChainBalanceKey (sourceChainId, account, token);
103
118
104
119
uint256 balance = dataStore.getUint (balanceKey);
105
120
if (balance < amount) {
@@ -112,6 +127,6 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
112
127
// transfer tokens to IMultichainProvider
113
128
multichainVault.transferOut (token, msg .sender , amount);
114
129
115
- MultichainEventUtils.emitMultichainWithdrawal (eventEmitter, token, virtualAccount , amount, sourceChainId);
130
+ MultichainEventUtils.emitMultichainWithdrawal (eventEmitter, token, account , amount, sourceChainId);
116
131
}
117
132
}
0 commit comments