└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # hyperlane-smart-contract 2 | // SPDX-License-Identifier: MIT 3 | pragma solidity ^0.8.0; 4 | 5 | import "@hyperlane-xyz/core/contracts/interfaces/IMessageRecipient.sol"; 6 | import "@hyperlane-xyz/core/contracts/interfaces/IMailbox.sol"; 7 | 8 | contract HyperlaneBridge is IMessageRecipient { 9 | address public admin; 10 | IMailbox public mailbox; 11 | mapping(bytes32 => bool) public processedMessages; 12 | 13 | event TokensLocked(address indexed user, uint256 amount, address token, uint32 destinationChain, bytes32 messageId); 14 | event TokensUnlocked(address indexed user, uint256 amount, address token, bytes32 messageId); 15 | event CrossChainMessageReceived(uint32 origin, bytes32 sender, string message); 16 | 17 | constructor(address _mailbox) { 18 | admin = msg.sender; 19 | mailbox = IMailbox(_mailbox); 20 | } 21 | 22 | modifier onlyAdmin() { 23 | require(msg.sender == admin, "Only admin can perform this action"); 24 | _; 25 | } 26 | 27 | function lockTokens(address token, uint256 amount, uint32 destinationChain) external { 28 | require(amount > 0, "Amount must be greater than 0"); 29 | require(IERC20(token).transferFrom(msg.sender, address(this), amount), "Transfer failed"); 30 | 31 | bytes32 messageId = keccak256(abi.encodePacked(msg.sender, amount, token, destinationChain, block.timestamp)); 32 | emit TokensLocked(msg.sender, amount, token, destinationChain, messageId); 33 | } 34 | 35 | function unlockTokens(address user, address token, uint256 amount, bytes32 messageId) external onlyAdmin { 36 | require(!processedMessages[messageId], "Message already processed"); 37 | require(IERC20(token).balanceOf(address(this)) >= amount, "Not enough liquidity"); 38 | 39 | processedMessages[messageId] = true; 40 | require(IERC20(token).transfer(user, amount), "Transfer failed"); 41 | emit TokensUnlocked(user, amount, token, messageId); 42 | } 43 | 44 | function receiveMessage(uint32 _origin, bytes32 _sender, bytes calldata _body) external override { 45 | require(msg.sender == address(mailbox), "Unauthorized sender"); 46 | require(!processedMessages[keccak256(_body)], "Message already processed"); 47 | 48 | string memory message = string(_body); 49 | processedMessages[keccak256(_body)] = true; 50 | emit CrossChainMessageReceived(_origin, _sender, message); 51 | } 52 | 53 | function sendCrossChainMessage(uint32 _destinationDomain, address _recipient, string calldata _message) external onlyAdmin { 54 | bytes memory body = bytes(_message); 55 | mailbox.dispatch(_destinationDomain, bytes32(uint256(uint160(_recipient))), body); 56 | } 57 | } 58 | 1234 59 | --------------------------------------------------------------------------------