22
33pragma solidity ^ 0.8.0 ;
44
5+ import "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
6+ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol " ;
7+
58import { RoleStore } from "../role/RoleStore.sol " ;
69import { RoleModule } from "../role/RoleModule.sol " ;
710import { DataStore } from "../data/DataStore.sol " ;
@@ -21,6 +24,8 @@ import { MultichainEventUtils } from "./MultichainEventUtils.sol";
2124 * @title MultichainHandler
2225 */
2326contract MultichainHandler is RoleModule , GlobalReentrancyGuard , OracleModule {
27+ using SafeERC20 for IERC20 ;
28+
2429 MultichainVault public multichainVault;
2530 EventEmitter public eventEmitter;
2631 ExchangeRouter public exchangeRouter;
@@ -39,7 +44,7 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
3944 }
4045
4146 /**
42- * Records a deposit from another chain. IMultichainProvider has MULTICHAIN_CONTROLLER role
47+ * Records a deposit from another chain. IMultichainProvider has CONTROLLER role
4348 * @param account user address on the source chain
4449 * @param token address of the token being deposited
4550 * @param sourceChainId chain id of the source chain
@@ -48,18 +53,30 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
4853 address account ,
4954 address token ,
5055 uint256 sourceChainId
51- ) external onlyController returns ( address virtualAccount ) {
56+ ) external onlyController {
5257 // token should have been transferred to multichainVault by IMultichainProvider
5358 uint256 amount = multichainVault.recordTransferIn (token);
5459 if (amount == 0 ) {
5560 revert Errors.EmptyMultichainDepositAmount ();
5661 }
5762
58- virtualAccount = MultichainUtils. getVirtualAccount ( account, sourceChainId );
63+ dataStore. incrementUint (Keys. sourceChainBalanceKey (sourceChainId, account, token), amount );
5964
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);
6178
62- MultichainEventUtils. emitMultichainDeposit (eventEmitter, token, virtualAccount, amount, sourceChainId );
79+ IERC20 (token). safeTransferFrom (account, receiver, amount);
6380 }
6481
6582 /**
@@ -77,12 +94,11 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
7794 // execute multicall
7895 exchangeRouter.multicall (multicallArgs);
7996
80- address virtualAccount = MultichainUtils.getVirtualAccount (account, sourceChainId);
81- MultichainEventUtils.emitMultichainMessage (eventEmitter, virtualAccount, sourceChainId);
97+ MultichainEventUtils.emitMultichainMessage (eventEmitter, account, sourceChainId);
8298 }
8399
84100 /**
85- * Record a withdrawal to another chain. IMultichainProvider has MULTICHAIN_CONTROLLER role
101+ * Record a withdrawal to another chain. IMultichainProvider has CONTROLLER role
86102 * @param account user address on the source chain
87103 * @param token address of the token being withdrawn
88104 * @param amount amount of token being withdrawn
@@ -98,8 +114,7 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
98114 revert Errors.EmptyMultichainWithdrawalAmount ();
99115 }
100116
101- address virtualAccount = MultichainUtils.getVirtualAccount (account, sourceChainId);
102- bytes32 balanceKey = Keys.sourceChainBalanceKey (virtualAccount, token);
117+ bytes32 balanceKey = Keys.sourceChainBalanceKey (sourceChainId, account, token);
103118
104119 uint256 balance = dataStore.getUint (balanceKey);
105120 if (balance < amount) {
@@ -112,6 +127,6 @@ contract MultichainHandler is RoleModule, GlobalReentrancyGuard, OracleModule {
112127 // transfer tokens to IMultichainProvider
113128 multichainVault.transferOut (token, msg .sender , amount);
114129
115- MultichainEventUtils.emitMultichainWithdrawal (eventEmitter, token, virtualAccount , amount, sourceChainId);
130+ MultichainEventUtils.emitMultichainWithdrawal (eventEmitter, token, account , amount, sourceChainId);
116131 }
117132}
0 commit comments