Skip to content

Commit

Permalink
feat: test B -> A route
Browse files Browse the repository at this point in the history
  • Loading branch information
sujithsomraaj committed Nov 10, 2023
1 parent 8534156 commit 0884268
Show file tree
Hide file tree
Showing 7 changed files with 307 additions and 326 deletions.
62 changes: 32 additions & 30 deletions src/adapters/axelar/AxelarReceiverAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,26 @@ contract AxelarReceiverAdapter is BaseReceiverAdapter, IAxelarExecutable {

string public constant name = "AXELAR";

IAxelarGateway public immutable gateway;
IAxelarGateway public gateway;

/*/////////////////////////////////////////////////////////////////
STATE VARIABLES
////////////////////////////////////////////////////////////////*/
string public senderChainId;

mapping(bytes32 => bool) public isMessageExecuted;
mapping(bytes32 => bool) public commandIdStatus;

/*/////////////////////////////////////////////////////////////////
CONSTRUCTOR
////////////////////////////////////////////////////////////////*/
/// @param _gateway is axelar gateway contract address.
/// @param _senderChainId is the chain id of the sender chain.
/// @param _receiverGAC is global access controller.
constructor(address _gateway, string memory _senderChainId, address _receiverGAC)
BaseReceiverAdapter(_receiverGAC)
{
constructor(address _receiverGAC) BaseReceiverAdapter(_receiverGAC) {}

function setAxelarConfig(address _gateway) external onlyGlobalOwner {
if (_gateway == address(0)) {
revert Error.ZERO_ADDRESS_INPUT();
}

if (bytes(_senderChainId).length == 0) {
revert Error.INVALID_SENDER_CHAIN_ID();
}

gateway = IAxelarGateway(_gateway);
senderChainId = _senderChainId;
}

/*/////////////////////////////////////////////////////////////////
Expand All @@ -65,46 +56,57 @@ contract AxelarReceiverAdapter is BaseReceiverAdapter, IAxelarExecutable {
string calldata _sourceAddress,
bytes calldata _payload
) external override {
/// @dev step-1: validate incoming chain id
if (keccak256(bytes(_sourceChainId)) != keccak256(bytes(senderChainId))) {
revert Error.INVALID_SENDER_CHAIN_ID();
}

/// @dev step-2: validate the source address
/// @dev step-1: validate the source address
if (_sourceAddress.toAddress() != senderAdapter) {
revert Error.INVALID_SENDER_ADAPTER();
}

/// @dev step-3: validate the contract call
if (!gateway.validateContractCall(_commandId, _sourceChainId, _sourceAddress, keccak256(_payload))) {
/// @dev step-2: validate the contract call
if (
!gateway.validateContractCall(
_commandId,
_sourceChainId,
_sourceAddress,
keccak256(_payload)
)
) {
revert Error.NOT_APPROVED_BY_GATEWAY();
}

/// decode the cross-chain payload
AdapterPayload memory decodedPayload = abi.decode(_payload, (AdapterPayload));
AdapterPayload memory decodedPayload = abi.decode(
_payload,
(AdapterPayload)
);
bytes32 msgId = decodedPayload.msgId;

/// @dev step-4: check for duplicate message
/// @dev step-3: check for duplicate message
if (commandIdStatus[_commandId] || isMessageExecuted[msgId]) {
revert MessageIdAlreadyExecuted(msgId);
}

/// @dev step-5: validate the receive adapter
/// @dev step-4: validate the receive adapter
if (decodedPayload.receiverAdapter != address(this)) {
revert Error.INVALID_RECEIVER_ADAPTER();
}

/// @dev step-6: validate the destination
if (decodedPayload.finalDestination != receiverGAC.multiBridgeMsgReceiver()) {
revert Error.INVALID_FINAL_DESTINATION();
}
/// @dev step-5: validate the destination
// if (decodedPayload.finalDestination != receiverGAC.multiBridgeMsgReceiver()) {
// revert Error.INVALID_FINAL_DESTINATION();
// }

isMessageExecuted[msgId] = true;
commandIdStatus[_commandId] = true;

MessageLibrary.Message memory _data = abi.decode(decodedPayload.data, (MessageLibrary.Message));
MessageLibrary.Message memory _data = abi.decode(
decodedPayload.data,
(MessageLibrary.Message)
);

try IMultiBridgeMessageReceiver(decodedPayload.finalDestination).receiveMessage(_data) {
try
IMultiBridgeMessageReceiver(receiverGAC.multiBridgeMsgReceiver())
.receiveMessage(_data)
{
emit MessageIdExecuted(_data.srcChainId, msgId);
} catch (bytes memory lowLevelData) {
revert MessageFailure(msgId, lowLevelData);
Expand Down
53 changes: 41 additions & 12 deletions src/adapters/axelar/AxelarSenderAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,28 @@ import "./libraries/StringAddressConversion.sol";

contract AxelarSenderAdapter is BaseSenderAdapter {
/// @notice event emitted when a chain id mapping is updated
event ChainIDMappingUpdated(uint256 indexed origId, string oldAxlId, string newAxlId);
event ChainIDMappingUpdated(
uint256 indexed origId,
string oldAxlId,
string newAxlId
);

string public constant name = "AXELAR";

IAxelarGateway public immutable gateway;
IAxelarGateway public gateway;
IAxelarGasService public gasService;

/*/////////////////////////////////////////////////////////////////
STATE VARIABLES
////////////////////////////////////////////////////////////////*/
IAxelarGasService public immutable gasService;
mapping(uint256 => string) public chainIdMap;

/*/////////////////////////////////////////////////////////////////
CONSTRUCTOR
////////////////////////////////////////////////////////////////*/
constructor(address _gasService, address _gateway, address _gac) BaseSenderAdapter(_gac) {
constructor(address _gac) BaseSenderAdapter(_gac) {}

function setAxelarConfig(address _gasService, address _gateway) external onlyGlobalOwner {
if (_gasService == address(0) || _gateway == address(0)) {
revert Error.ZERO_ADDRESS_INPUT();
}
Expand All @@ -45,7 +51,11 @@ contract AxelarSenderAdapter is BaseSenderAdapter {
/// @param _receiverChainId The ID of the destination chain.
/// @param _to The address of the contract on the destination chain that will receive the message.
/// @param _data The data to be included in the message.
function dispatchMessage(uint256 _receiverChainId, address _to, bytes calldata _data)
function dispatchMessage(
uint256 _receiverChainId,
address _to,
bytes calldata _data
)
external
payable
override
Expand Down Expand Up @@ -73,14 +83,17 @@ contract AxelarSenderAdapter is BaseSenderAdapter {
/// @dev maps the MMA chain id to bridge specific chain id
/// @dev _origIds is the chain's native chain id
/// @dev _axlIds are the bridge allocated chain id
function setChainIdMap(uint256[] calldata _origIds, string[] calldata _axlIds) external onlyGlobalOwner {
function setChainIdMap(
uint256[] calldata _origIds,
string[] calldata _axlIds
) external onlyGlobalOwner {
uint256 arrLength = _origIds.length;

if (arrLength != _axlIds.length) {
revert Error.ARRAY_LENGTH_MISMATCHED();
}

for (uint256 i; i < arrLength;) {
for (uint256 i; i < arrLength; ) {
if (_origIds[i] == 0) {
revert Error.ZERO_CHAIN_ID();
}
Expand Down Expand Up @@ -113,14 +126,30 @@ contract AxelarSenderAdapter is BaseSenderAdapter {
address _multibridgeReceiver,
bytes calldata _data
) internal {
string memory receiverAdapterInString = StringAddressConversion.toString(_receiverAdapter);
bytes memory payload =
abi.encode(AdapterPayload(_msgId, address(msg.sender), _receiverAdapter, _multibridgeReceiver, _data));
string memory receiverAdapterInString = StringAddressConversion
.toString(_receiverAdapter);
bytes memory payload = abi.encode(
AdapterPayload(
_msgId,
address(msg.sender),
_receiverAdapter,
_multibridgeReceiver,
_data
)
);

gasService.payNativeGasForContractCall{value: msg.value}(
msg.sender, _destinationChain, receiverAdapterInString, payload, msg.sender
msg.sender,
_destinationChain,
receiverAdapterInString,
payload,
msg.sender
);

gateway.callContract(_destinationChain, receiverAdapterInString, payload);
gateway.callContract(
_destinationChain,
receiverAdapterInString,
payload
);
}
}
4 changes: 3 additions & 1 deletion src/adapters/wormhole/WormholeReceiverAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import "../../libraries/Message.sol";
import "../../controllers/MessageReceiverGAC.sol";
import "../BaseReceiverAdapter.sol";

import "forge-std/console.sol";

/// @notice receiver adapter for wormhole bridge
/// @dev allows wormhole relayers to write to receiver adapter which then forwards the message to
/// the MMA receiver.
Expand Down Expand Up @@ -89,7 +91,7 @@ contract WormholeReceiverAdapter is BaseReceiverAdapter, IWormholeReceiver {
if (decodedPayload.receiverAdapter != address(this)) {
revert Error.INVALID_RECEIVER_ADAPTER();
}

/// @dev step-4: validate the destination
if (decodedPayload.finalDestination != receiverGAC.multiBridgeMsgReceiver()) {
revert Error.INVALID_FINAL_DESTINATION();
Expand Down
24 changes: 14 additions & 10 deletions src/token/xERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// local imports
import {IXERC20} from "src/interfaces/EIP7281/IXERC20.sol";

interface IBridge {
interface IMultiMessageSender {
function remoteCall(
uint256 _dstChainId,
address _target,
Expand All @@ -21,19 +21,22 @@ interface IBridge {
}

contract xERC20 is IXERC20, ERC20 {
IBridge public bridge;
IMultiMessageSender public mmaSender;
address public mmaReceiver;

modifier onlyBridge() {
require(msg.sender == address(bridge), "xERC20: invalid caller");
modifier onlyMultiMessageReceiver() {
require(msg.sender == address(mmaReceiver), "xERC20: invalid caller");
_;
}

constructor(
string memory _name,
string memory _symbol,
address _bridge
address _mmaSender,
address _mmaReceiver
) ERC20(_name, _symbol) {
bridge = IBridge(_bridge);
mmaSender = IMultiMessageSender(_mmaSender);
mmaReceiver = _mmaReceiver;

/// @dev mints 1 million tokens
_mint(msg.sender, 1e24);
Expand All @@ -50,7 +53,7 @@ contract xERC20 is IXERC20, ERC20 {
/// assume CREATE2
/// assume msg has 29 day expiration
/// assume msg.sender as refund address
bridge.remoteCall{value: msg.value}(
mmaSender.remoteCall{value: msg.value}(
_dstChainId,
address(this),
bytes(""),
Expand All @@ -71,12 +74,13 @@ contract xERC20 is IXERC20, ERC20 {
uint256 _burningLimit
) external override {}

function mint(address _user, uint256 _amount) external override onlyBridge {
function mint(address _user, uint256 _amount) external override onlyMultiMessageReceiver {
_mint(_user, _amount);
}

function burn(address _user, uint256 _amount) external override onlyBridge {
_burn(_user, _amount);
function burn(address _user, uint256 _amount) external override {
/// @notice no use case for now
revert();
}

function mintingMaxLimitOf(
Expand Down
97 changes: 0 additions & 97 deletions src/xERC20.sol

This file was deleted.

Loading

0 comments on commit 0884268

Please sign in to comment.