Skip to content

Commit

Permalink
Remove AgentExecuteCommand
Browse files Browse the repository at this point in the history
  • Loading branch information
yrong committed Apr 9, 2024
1 parent 32f8d86 commit b2a666a
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 74 deletions.
2 changes: 1 addition & 1 deletion contracts/src/AgentExecutor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-FileCopyrightText: 2023 Snowfork <[email protected]>
pragma solidity 0.8.23;

import {AgentExecuteCommand, ParaID} from "./Types.sol";
import {ParaID} from "./Types.sol";
import {SubstrateTypes} from "./SubstrateTypes.sol";

import {IERC20} from "./interfaces/IERC20.sol";
Expand Down
55 changes: 25 additions & 30 deletions contracts/src/Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import {
MultiAddress,
Ticket,
Costs,
TokenInfo,
AgentExecuteCommand
TokenInfo
} from "./Types.sol";
import {IGateway} from "./interfaces/IGateway.sol";
import {IInitializable} from "./interfaces/IInitializable.sol";
Expand All @@ -33,14 +32,15 @@ import {ScaleCodec} from "./utils/ScaleCodec.sol";
import {
UpgradeParams,
CreateAgentParams,
AgentExecuteParams,
CreateChannelParams,
UpdateChannelParams,
SetOperatingModeParams,
TransferNativeFromAgentParams,
SetTokenTransferFeesParams,
SetPricingParametersParams,
RegisterForeignTokenParams
RegisterForeignTokenParams,
MintForeignTokenParams,
TransferTokenParams
} from "./Params.sol";

import {CoreStorage} from "./storage/CoreStorage.sol";
Expand Down Expand Up @@ -85,7 +85,6 @@ contract Gateway is IGateway, IInitializable {
error ChannelAlreadyCreated();
error ChannelDoesNotExist();
error InvalidChannelUpdate();
error AgentExecutionFailed(bytes returndata);
error InvalidAgentExecutionPayload();
error InvalidCodeHash();
error InvalidConstructorParams();
Expand Down Expand Up @@ -170,8 +169,8 @@ contract Gateway is IGateway, IInitializable {
bool success = true;

// Dispatch message to a handler
if (message.command == Command.AgentExecute) {
try Gateway(this).agentExecute{gas: maxDispatchGas}(message.params) {}
if (message.command == Command.TransferToken) {
try Gateway(this).transferToken{gas: maxDispatchGas}(message.params) {}
catch {
success = false;
}
Expand Down Expand Up @@ -220,6 +219,11 @@ contract Gateway is IGateway, IInitializable {
catch {
success = false;
}
} else if (message.command == Command.MintForeignToken) {
try Gateway(this).mintForeignToken{gas: maxDispatchGas}(message.params) {}
catch {
success = false;
}
}

// Calculate a gas refund, capped to protect against huge spikes in `tx.gasprice`
Expand Down Expand Up @@ -273,29 +277,6 @@ contract Gateway is IGateway, IInitializable {
* Handlers
*/

// Execute code within an agent
function agentExecute(bytes calldata data) external onlySelf {
AgentExecuteParams memory params = abi.decode(data, (AgentExecuteParams));

address agent = _ensureAgent(params.agentID);

if (params.payload.length == 0) {
revert InvalidAgentExecutionPayload();
}

(AgentExecuteCommand command, bytes memory commandParams) =
abi.decode(params.payload, (AgentExecuteCommand, bytes));

if (command == AgentExecuteCommand.MintToken) {
(bytes32 tokenID, address recipient, uint256 amount) =
abi.decode(commandParams, (bytes32, address, uint256));
Assets.mintForeignToken(AGENT_EXECUTOR, agent, tokenID, recipient, amount);
} else if (command == AgentExecuteCommand.TransferToken) {
(address token, address recipient, uint128 amount) = abi.decode(commandParams, (address, address, uint128));
Assets.transferToken(AGENT_EXECUTOR, agent, token, recipient, amount);
}
}

/// @dev Create an agent for a consensus system on Polkadot
function createAgent(bytes calldata data) external onlySelf {
CoreStorage.Layout storage $ = CoreStorage.layout();
Expand Down Expand Up @@ -427,6 +408,20 @@ contract Gateway is IGateway, IInitializable {
Assets.registerForeignToken(params.agentID, agent, params.tokenID, params.name, params.symbol, params.decimals);
}

// @dev Mint foreign token from polkadot
function mintForeignToken(bytes calldata data) external onlySelf {
MintForeignTokenParams memory params = abi.decode(data, (MintForeignTokenParams));
address agent = _ensureAgent(params.agentID);
Assets.mintForeignToken(AGENT_EXECUTOR, agent, params.tokenID, params.recipient, params.amount);
}

// @dev Transfer Ethereum native token back from polkadot
function transferToken(bytes calldata data) external onlySelf {
TransferTokenParams memory params = abi.decode(data, (TransferTokenParams));
address agent = _ensureAgent(params.agentID);
Assets.transferToken(AGENT_EXECUTOR, agent, params.token, params.recipient, params.amount);
}

function isTokenRegistered(address token) external view returns (bool) {
return Assets.isTokenRegistered(token);
}
Expand Down
30 changes: 24 additions & 6 deletions contracts/src/Params.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ pragma solidity 0.8.23;
import {ChannelID, OperatingMode} from "./Types.sol";
import {UD60x18} from "prb/math/src/UD60x18.sol";

// Payload for AgentExecute
struct AgentExecuteParams {
bytes32 agentID;
bytes payload;
}

// Payload for CreateAgent
struct CreateAgentParams {
/// @dev The agent ID of the consensus system
Expand Down Expand Up @@ -96,3 +90,27 @@ struct RegisterForeignTokenParams {
/// @dev The decimal of the token
uint8 decimals;
}

// Payload for MintForeignToken
struct MintForeignTokenParams {
/// @dev The agent ID of the consensus system
bytes32 agentID;
/// @dev The token ID
bytes32 tokenID;
/// @dev The address of the recipient
address recipient;
/// @dev The amount to mint with
uint256 amount;
}

// Payload for TransferToken
struct TransferTokenParams {
/// @dev The agent ID of the consensus system
bytes32 agentID;
/// @dev The token address
address token;
/// @dev The address of the recipient
address recipient;
/// @dev The amount to mint with
uint128 amount;
}
10 changes: 3 additions & 7 deletions contracts/src/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ enum OperatingMode {

/// @dev Messages from Polkadot take the form of these commands.
enum Command {
AgentExecute,
TransferToken,
Upgrade,
CreateAgent,
CreateChannel,
Expand All @@ -85,12 +85,8 @@ enum Command {
TransferNativeFromAgent,
SetTokenTransferFees,
SetPricingParameters,
RegisterForeignToken
}

enum AgentExecuteCommand {
TransferToken,
MintToken
RegisterForeignToken,
MintForeignToken
}

/// @dev Application-level costs for a message
Expand Down
40 changes: 14 additions & 26 deletions contracts/test/Gateway.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ import {PricingStorage} from "../src/storage/PricingStorage.sol";
import {
UpgradeParams,
CreateAgentParams,
AgentExecuteParams,
CreateChannelParams,
UpdateChannelParams,
SetOperatingModeParams,
TransferNativeFromAgentParams,
SetTokenTransferFeesParams,
SetPricingParametersParams,
RegisterForeignTokenParams
RegisterForeignTokenParams,
TransferTokenParams,
MintForeignTokenParams
} from "../src/Params.sol";

import {
AgentExecuteCommand,
InboundMessage,
OperatingMode,
ParaID,
Expand Down Expand Up @@ -351,30 +351,19 @@ contract GatewayTest is Test {
function testAgentExecution() public {
token.transfer(address(assetHubAgent), 200);

AgentExecuteParams memory params = AgentExecuteParams({
agentID: assetHubAgentID,
payload: abi.encode(AgentExecuteCommand.TransferToken, abi.encode(address(token), address(account2), 10))
});
TransferTokenParams memory params =
TransferTokenParams({agentID: assetHubAgentID, token: address(token), recipient: account2, amount: 10});

bytes memory encodedParams = abi.encode(params);
GatewayMock(address(gateway)).agentExecutePublic(encodedParams);
GatewayMock(address(gateway)).transferTokenPublic(encodedParams);
}

function testAgentExecutionBadOrigin() public {
AgentExecuteParams memory params = AgentExecuteParams({
agentID: bytes32(0),
payload: abi.encode(keccak256("transferNativeToken"), abi.encode(address(token), address(this), 1))
});
TransferNativeFromAgentParams memory params =
TransferNativeFromAgentParams({agentID: bytes32(0), recipient: address(this), amount: 1});

vm.expectRevert(Gateway.AgentDoesNotExist.selector);
GatewayMock(address(gateway)).agentExecutePublic(abi.encode(params));
}

function testAgentExecutionBadPayload() public {
AgentExecuteParams memory params = AgentExecuteParams({agentID: assetHubAgentID, payload: ""});

vm.expectRevert(Gateway.InvalidAgentExecutionPayload.selector);
GatewayMock(address(gateway)).agentExecutePublic(abi.encode(params));
GatewayMock(address(gateway)).transferNativeFromAgentPublic(abi.encode(params));
}

function testCreateAgent() public {
Expand Down Expand Up @@ -797,9 +786,6 @@ contract GatewayTest is Test {

// Handler functions should not be externally callable
function testHandlersNotExternallyCallable() public {
vm.expectRevert(Gateway.Unauthorized.selector);
Gateway(address(gateway)).agentExecute("");

vm.expectRevert(Gateway.Unauthorized.selector);
Gateway(address(gateway)).createAgent("");

Expand Down Expand Up @@ -941,15 +927,17 @@ contract GatewayTest is Test {

uint256 amount = 1000;

AgentExecuteParams memory params = AgentExecuteParams({
MintForeignTokenParams memory params = MintForeignTokenParams({
agentID: assetHubAgentID,
payload: abi.encode(AgentExecuteCommand.MintToken, abi.encode(bytes32(uint256(1)), account1, amount))
tokenID: bytes32(uint256(1)),
recipient: account1,
amount: amount
});

vm.expectEmit(true, true, false, false);
emit Transfer(address(0), account1, 1000);

GatewayMock(address(gateway)).agentExecutePublic(abi.encode(params));
GatewayMock(address(gateway)).mintForeignTokenPublic(abi.encode(params));

address dotToken = GatewayMock(address(gateway)).tokenAddressOf(dotTokenID);

Expand Down
12 changes: 8 additions & 4 deletions contracts/test/mocks/GatewayMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ contract GatewayMock is Gateway {
uint8 foreignTokenDecimals
) Gateway(beefyClient, agentExecutor, bridgeHubParaID, bridgeHubHubAgentID, foreignTokenDecimals) {}

function agentExecutePublic(bytes calldata params) external {
this.agentExecute(params);
}

function createAgentPublic(bytes calldata params) external {
this.createAgent(params);
}
Expand Down Expand Up @@ -76,6 +72,14 @@ contract GatewayMock is Gateway {
function registerForeignTokenPublic(bytes calldata params) external {
this.registerForeignToken(params);
}

function mintForeignTokenPublic(bytes calldata params) external {
this.mintForeignToken(params);
}

function transferTokenPublic(bytes calldata params) external {
this.transferToken(params);
}
}

library AdditionalStorage {
Expand Down

0 comments on commit b2a666a

Please sign in to comment.