Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/axelar proxy #118

Merged
merged 15 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions script/test/Arbitrum/DeployProxy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import { AxelarProxy } from "src/AxelarProxy.sol";

import "forge-std/Script.sol";
import { Math } from "src/utils/Math.sol";

/**
* @dev Run
* `source .env && forge script script/test/Arbitrum/DeployProxy.s.sol:DeployProxyScript --rpc-url $ARBITRUM_RPC_URL --private-key $PRIVATE_KEY —optimize —optimizer-runs 200 --verify --etherscan-api-key $ARBISCAN_KEY --slow --broadcast`
* @dev Optionally can change `--with-gas-price` to something more reasonable
*/
contract DeployProxyScript is Script {
address private devOwner = 0x552acA1343A6383aF32ce1B7c7B1b47959F7ad90;

address private gateway = 0xe432150cce91c13a887f7D836923d5597adD8E31;

string private sourceChain = "Polygon";
string private sourceAddress = "0x552acA1343A6383aF32ce1B7c7B1b47959F7ad90";

function run() external {
vm.startBroadcast();

AxelarProxy proxy = new AxelarProxy(gateway);

vm.stopBroadcast();
}
}
41 changes: 41 additions & 0 deletions script/test/Polygon/SendMessageToArbitrum.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import { ERC20 } from "src/base/Cellar.sol";
import { AxelarProxy } from "src/AxelarProxy.sol";
import { MockSommelier } from "src/mocks/MockSommelier.sol";

import "forge-std/Script.sol";
import { Math } from "src/utils/Math.sol";

interface Gateway {
function callContract(string memory dest, string memory destAddress, bytes memory payload) external;
}

/**
* @dev Run
* `source .env && forge script script/test/Polygon/SendMessageToArbitrum.s.sol:SendMessageToArbitrumScript --rpc-url $MATIC_RPC_URL --private-key $PRIVATE_KEY —optimize —optimizer-runs 200 --verify --etherscan-api-key $POLYGONSCAN_KEY --slow --broadcast`
* @dev Optionally can change `--with-gas-price` to something more reasonable
*/
contract SendMessageToArbitrumScript is Script {
address private devOwner = 0x552acA1343A6383aF32ce1B7c7B1b47959F7ad90;

Gateway private gateway = Gateway(0x6f015F16De9fC8791b234eF68D486d2bF203FBA8);

string private destChain = "arbitrum";
string private destAddress = "0x2aF45D06C3d06af1E6B8Bc3f90c5a8DB0E5aa729";

address private usdcOnArb = 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8;

MockSommelier private mockSomm;

function run() external {
vm.startBroadcast();

mockSomm = new MockSommelier();

mockSomm.sendMessage{ value: 10 ether }(destAddress, usdcOnArb, devOwner, 777);
0xEinCodes marked this conversation as resolved.
Show resolved Hide resolved

vm.stopBroadcast();
}
}
47 changes: 47 additions & 0 deletions src/AxelarProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import { AxelarExecutable } from "lib/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";

crispymangoes marked this conversation as resolved.
Show resolved Hide resolved
contract AxelarProxy is AxelarExecutable {
0xEinCodes marked this conversation as resolved.
Show resolved Hide resolved
using Address for address;

event LogicCallEvent(address target, bytes callData);

error AxelarProxy__WrongSource();
error AxelarProxy__NoTokens();

bytes32 public constant SOMMELIER_CHAIN_HASH = keccak256(bytes("sommelier"));

constructor(address gateway_) AxelarExecutable(gateway_) {}

/**
* @notice Execution logic.
* @dev Verifies message is from Sommelier, otherwise reverts.
0xEinCodes marked this conversation as resolved.
Show resolved Hide resolved
*/
function _execute(string calldata sourceChain, string calldata, bytes calldata payload) internal override {
crispymangoes marked this conversation as resolved.
Show resolved Hide resolved
// Validate Source Chain
if (keccak256(bytes(sourceChain)) != SOMMELIER_CHAIN_HASH) revert AxelarProxy__WrongSource();

// Execute function call.
(address target, bytes memory callData) = abi.decode(payload, (address, bytes));
0xEinCodes marked this conversation as resolved.
Show resolved Hide resolved
target.functionCall(callData);

emit LogicCallEvent(target, callData);
}

/**
* @notice Execution with token logic.
* @dev Not supported.
crispymangoes marked this conversation as resolved.
Show resolved Hide resolved
*/
function _executeWithToken(
string calldata,
string calldata,
bytes calldata,
string calldata,
uint256
) internal pure override {
revert AxelarProxy__NoTokens();
}
}
32 changes: 32 additions & 0 deletions src/mocks/MockSommelier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { ERC20 } from "src/base/Cellar.sol";
import { IAxelarGateway } from "lib/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol";
import { IAxelarGasService } from "lib/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol";

contract MockSommelier {
0xEinCodes marked this conversation as resolved.
Show resolved Hide resolved
using Address for address;

address constant ARB_USDC = 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8;
IAxelarGateway private axelarGateway = IAxelarGateway(0x6f015F16De9fC8791b234eF68D486d2bF203FBA8);
IAxelarGasService private axelarGasService = IAxelarGasService(0x2d5d7d31F671F86C782533cc367F14109a082712);
string private destChain = "arbitrum";

function sendMessage(string memory target, address token, address spender, uint256 amount) external payable {
bytes memory payload = abi.encodeWithSelector(ERC20.approve.selector, spender, amount);
payload = abi.encode(token, payload);

// Pay gas.
axelarGasService.payNativeGasForContractCall{ value: msg.value }(
msg.sender,
destChain,
target,
payload,
msg.sender
);
// Send GMP.
axelarGateway.callContract(destChain, target, payload);
}
}