Skip to content

Commit 130e4a1

Browse files
committed
PoC implementation of Zetachain crosschain contract
1 parent 0b34bf3 commit 130e4a1

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity ^0.8.20;
3+
4+
import {Module} from "../../../Module.sol";
5+
6+
import {Role} from "../../../Role.sol";
7+
import {IERC20} from "../../../interface/IERC20.sol";
8+
9+
library ZetaChainCrossChainStorage {
10+
11+
/// @custom:storage-location erc7201:token.minting.mintable
12+
bytes32 public constant ZETACHAIN_CROSS_CHAIN_STORAGE_POSITION =
13+
keccak256(abi.encode(uint256(keccak256("token.crosschain.zetachain")) - 1)) & ~bytes32(uint256(0xff));
14+
15+
struct Data {
16+
address erc20Custody;
17+
address tss;
18+
}
19+
20+
function data() internal pure returns (Data storage data_) {
21+
bytes32 position = ZETACHAIN_CROSS_CHAIN_STORAGE_POSITION;
22+
assembly {
23+
data_.slot := position
24+
}
25+
}
26+
27+
}
28+
29+
interface IERC20Custody {
30+
31+
function deposit(bytes calldata recipient, IERC20 asset, uint256 amount, bytes calldata message) external;
32+
33+
}
34+
35+
contract ZetaChainCrossChain is Module {
36+
37+
/*//////////////////////////////////////////////////////////////
38+
MODULE CONFIG
39+
//////////////////////////////////////////////////////////////*/
40+
41+
function getModuleConfig() external pure virtual override returns (ModuleConfig memory config) {
42+
config.callbackFunctions = new CallbackFunction[](1);
43+
config.fallbackFunctions = new FallbackFunction[](5);
44+
45+
config.fallbackFunctions[0] = FallbackFunction({selector: this.sendMessage.selector, permissionBits: 0});
46+
config.fallbackFunctions[2] = FallbackFunction({selector: this.getTss.selector, permissionBits: 0});
47+
config.fallbackFunctions[4] = FallbackFunction({selector: this.getERC20Custody.selector, permissionBits: 0});
48+
config.fallbackFunctions[1] =
49+
FallbackFunction({selector: this.setTss.selector, permissionBits: Role._MANAGER_ROLE});
50+
config.fallbackFunctions[3] =
51+
FallbackFunction({selector: this.setERC20Custody.selector, permissionBits: Role._MANAGER_ROLE});
52+
53+
config.registerInstallationCallback = true;
54+
}
55+
56+
/*//////////////////////////////////////////////////////////////
57+
CALLBACK FUNCTIONS
58+
//////////////////////////////////////////////////////////////*/
59+
60+
/// @dev Called by a Core into an Module during the installation of the Module.
61+
function onInstall(bytes calldata data) external {
62+
(address tss, address erc20Custody) = abi.decode(data, (address, address));
63+
_zetaChainCrossChainStorage().tss = tss;
64+
_zetaChainCrossChainStorage().erc20Custody = erc20Custody;
65+
}
66+
67+
/// @dev Called by a Core into an Module during the uninstallation of the Module.
68+
function onUninstall(bytes calldata data) external {}
69+
70+
/*//////////////////////////////////////////////////////////////
71+
Encode install / uninstall data
72+
//////////////////////////////////////////////////////////////*/
73+
74+
/// @dev Returns bytes encoded install params, to be sent to `onInstall` function
75+
function encodeBytesOnInstall(address tss, address erc20Custody) external pure returns (bytes memory) {
76+
return abi.encode(tss, erc20Custody);
77+
}
78+
79+
/// @dev Returns bytes encoded uninstall params, to be sent to `onUninstall` function
80+
function encodeBytesOnUninstall() external pure returns (bytes memory) {
81+
return "";
82+
}
83+
84+
/*//////////////////////////////////////////////////////////////
85+
FALLBACK FUNCTIONS
86+
//////////////////////////////////////////////////////////////*/
87+
88+
function sendMessage(address recipient, address token, uint256 value, bytes memory data) external {
89+
if (token == address(0)) {
90+
(bool success,) = payable(_zetaChainCrossChainStorage().tss).call{value: value}(data);
91+
require(success, "Failed to send message");
92+
} else {
93+
IERC20Custody(_zetaChainCrossChainStorage().erc20Custody).deposit(
94+
abi.encode(recipient), IERC20(token), value, data
95+
);
96+
}
97+
}
98+
99+
function getTss() external view returns (address) {
100+
return _zetaChainCrossChainStorage().tss;
101+
}
102+
103+
function setTss(address _tss) external {
104+
_zetaChainCrossChainStorage().tss = _tss;
105+
}
106+
107+
function getERC20Custody() external view returns (address) {
108+
return _zetaChainCrossChainStorage().erc20Custody;
109+
}
110+
111+
function setERC20Custody(address _erc20Custody) external {
112+
_zetaChainCrossChainStorage().erc20Custody = _erc20Custody;
113+
}
114+
115+
function _zetaChainCrossChainStorage() internal pure returns (ZetaChainCrossChainStorage.Data storage) {
116+
return ZetaChainCrossChainStorage.data();
117+
}
118+
119+
}

0 commit comments

Comments
 (0)