Skip to content

Commit 48ee48c

Browse files
committed
WIP multichain
1 parent 233f187 commit 48ee48c

File tree

11 files changed

+237
-50
lines changed

11 files changed

+237
-50
lines changed

contracts/data/Keys.sol

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,13 +2098,15 @@ library Keys {
20982098
}
20992099

21002100
// @dev key for user's balance for a source chain, recorded under the user's virtual account
2101-
// @param virtualAccount the virtual account for which to retreive the user balance key
2101+
// @param chianId the chain id for the source chain
2102+
// @param account the account for which to retreive the user balance key
21022103
// @param token the token for which to retreive the user balance key
21032104
// @return key for a source chain balance for a given user and token
2104-
function sourceChainBalanceKey(address virtualAccount, address token) internal pure returns (bytes32) {
2105+
function sourceChainBalanceKey(uint256 chainId, address account, address token) internal pure returns (bytes32) {
21052106
return keccak256(abi.encode(
21062107
SOURCE_CHAIN_BALANCE,
2107-
virtualAccount,
2108+
chainId,
2109+
account,
21082110
token
21092111
));
21102112
}

contracts/multichain/LayerZeroProvider.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,12 @@ contract LayerZeroProvider is IMultichainProvider, ILayerZeroComposer {
6464

6565
_transferToVault(token, address(multichainVault));
6666

67-
address virtualAccount = multichainHandler.recordDeposit(account, token, sourceChainId);
67+
multichainHandler.recordDeposit(account, token, sourceChainId);
6868

6969
LayerZeroProviderEventUtils.emitComposedMessageReceived(
7070
eventEmitter,
71-
virtualAccount,
71+
sourceChainId,
72+
account,
7273
from,
7374
guid,
7475
message,

contracts/multichain/LayerZeroProviderEventUtils.sol

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ library LayerZeroProviderEventUtils {
1717

1818
function emitComposedMessageReceived(
1919
EventEmitter eventEmitter,
20-
address virtualAccount,
20+
uint256 sourceChainId,
21+
address account,
2122
address from,
2223
bytes32 guid,
2324
bytes calldata message,
@@ -27,9 +28,12 @@ library LayerZeroProviderEventUtils {
2728
EventUtils.EventLogData memory eventData;
2829

2930
eventData.addressItems.initItems(3);
30-
eventData.addressItems.setItem(0, "virtualAccount", virtualAccount);
31+
eventData.addressItems.setItem(0, "account", account);
3132
eventData.addressItems.setItem(1, "from", from);
3233
eventData.addressItems.setItem(2, "executor", executor);
34+
35+
eventData.uintItems.initItems(1);
36+
eventData.uintItems.setItem(0, "sourceChainId", sourceChainId);
3337

3438
eventData.bytes32Items.initItems(1);
3539
eventData.bytes32Items.setItem(0, "guid", guid);
@@ -38,12 +42,13 @@ library LayerZeroProviderEventUtils {
3842
eventData.bytesItems.setItem(0, "message", message);
3943
eventData.bytesItems.setItem(1, "extraData", extraData);
4044

41-
eventEmitter.emitEventLog1("MessageComposedReceived", Cast.toBytes32(virtualAccount), eventData);
45+
eventEmitter.emitEventLog2("MessageComposedReceived", bytes32(sourceChainId), Cast.toBytes32(account), eventData);
4246
}
4347

4448
function emitWithdrawalReceipt(
4549
EventEmitter eventEmitter,
46-
address virtualAccount,
50+
uint256 sourceChainId,
51+
address account,
4752
bytes32 guid,
4853
uint64 nonce,
4954
uint256 nativeFee,
@@ -53,16 +58,17 @@ library LayerZeroProviderEventUtils {
5358
) internal {
5459
EventUtils.EventLogData memory eventData;
5560

56-
eventData.uintItems.initItems(5);
61+
eventData.uintItems.initItems(6);
5762
eventData.uintItems.setItem(0, "nonce", uint256(nonce));
5863
eventData.uintItems.setItem(1, "nativeFee", nativeFee);
5964
eventData.uintItems.setItem(2, "lzTokenFee", lzTokenFee);
6065
eventData.uintItems.setItem(3, "amountSentLD", amountSentLD);
6166
eventData.uintItems.setItem(4, "amountReceivedLD", amountReceivedLD);
67+
eventData.uintItems.setItem(5, "sourceChainId", sourceChainId);
6268

6369
eventData.bytes32Items.initItems(1);
6470
eventData.bytes32Items.setItem(0, "guid", guid);
6571

66-
eventEmitter.emitEventLog1("WithdrawalReceipt", Cast.toBytes32(virtualAccount), eventData);
72+
eventEmitter.emitEventLog2("WithdrawalReceipt", bytes32(sourceChainId), Cast.toBytes32(account), eventData);
6773
}
6874
}

contracts/multichain/MultichainEventUtils.sol

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,56 +16,56 @@ library MultichainEventUtils {
1616
function emitMultichainDeposit(
1717
EventEmitter eventEmitter,
1818
address token,
19-
address virtualAccount,
19+
address account,
2020
uint256 amount,
2121
uint256 sourceChainId
2222
) internal {
2323
EventUtils.EventLogData memory eventData;
2424

2525
eventData.addressItems.initItems(2);
2626
eventData.addressItems.setItem(0, "token", token);
27-
eventData.addressItems.setItem(1, "virtualAccount", virtualAccount);
27+
eventData.addressItems.setItem(1, "account", account);
2828

2929
eventData.uintItems.initItems(2);
3030
eventData.uintItems.setItem(0, "amount", amount);
3131
eventData.uintItems.setItem(1, "sourceChainId", sourceChainId);
3232

33-
eventEmitter.emitEventLog1("MultichainDeposit", Cast.toBytes32(virtualAccount), eventData);
33+
eventEmitter.emitEventLog2("MultichainDeposit", bytes32(sourceChainId), Cast.toBytes32(account), eventData);
3434
}
3535

3636
function emitMultichainMessage(
3737
EventEmitter eventEmitter,
38-
address virtualAccount,
38+
address account,
3939
uint256 sourceChainId
4040
) internal {
4141
EventUtils.EventLogData memory eventData;
4242

4343
eventData.addressItems.initItems(1);
44-
eventData.addressItems.setItem(0, "virtualAccount", virtualAccount);
44+
eventData.addressItems.setItem(0, "account", account);
4545

4646
eventData.uintItems.initItems(1);
4747
eventData.uintItems.setItem(0, "sourceChainId", sourceChainId);
4848

49-
eventEmitter.emitEventLog1("MultichainMessage", Cast.toBytes32(virtualAccount), eventData);
49+
eventEmitter.emitEventLog1("MultichainMessage", Cast.toBytes32(account), eventData);
5050
}
5151

5252
function emitMultichainWithdrawal(
5353
EventEmitter eventEmitter,
5454
address token,
55-
address virtualAccount,
55+
address account,
5656
uint256 amount,
5757
uint256 sourceChainId
5858
) internal {
5959
EventUtils.EventLogData memory eventData;
6060

6161
eventData.addressItems.initItems(2);
6262
eventData.addressItems.setItem(0, "token", token);
63-
eventData.addressItems.setItem(1, "virtualAccount", virtualAccount);
63+
eventData.addressItems.setItem(1, "account", account);
6464

6565
eventData.uintItems.initItems(2);
6666
eventData.uintItems.setItem(0, "amount", amount);
6767
eventData.uintItems.setItem(1, "sourceChainId", sourceChainId);
6868

69-
eventEmitter.emitEventLog1("MultichainWithdrawal", Cast.toBytes32(virtualAccount), eventData);
69+
eventEmitter.emitEventLog2("MultichainWithdrawal", bytes32(sourceChainId), Cast.toBytes32(account), eventData);
7070
}
7171
}

contracts/multichain/MultichainHandler.sol

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
pragma solidity ^0.8.0;
44

5+
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
6+
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
7+
58
import { RoleStore } from "../role/RoleStore.sol";
69
import { RoleModule } from "../role/RoleModule.sol";
710
import { DataStore } from "../data/DataStore.sol";
@@ -21,6 +24,8 @@ import { MultichainEventUtils } from "./MultichainEventUtils.sol";
2124
* @title MultichainHandler
2225
*/
2326
contract 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

Comments
 (0)