Skip to content

Commit

Permalink
Move handler to Assets.sol reduce contract size
Browse files Browse the repository at this point in the history
  • Loading branch information
yrong committed Apr 4, 2024
1 parent b00538f commit 3da6be4
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 46 deletions.
51 changes: 51 additions & 0 deletions contracts/src/Assets.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {Address} from "./utils/Address.sol";
import {AgentExecutor} from "./AgentExecutor.sol";
import {Agent} from "./Agent.sol";
import {Call} from "./utils/Call.sol";
import {ERC20} from "./ERC20.sol";

/// @title Library for implementing Ethereum->Polkadot ERC20 transfers.
library Assets {
Expand All @@ -30,6 +31,8 @@ library Assets {
error Unsupported();
error InvalidDestinationFee();
error AgentDoesNotExist();
error TokenAlreadyRegistered();
error TokenMintFailed();

function isTokenRegistered(address token) external view returns (bool) {
return AssetsStorage.layout().tokenRegistry[token].isRegistered;
Expand Down Expand Up @@ -231,4 +234,52 @@ library Assets {
costs.foreign = destinationChainFee;
costs.native = 0;
}

// @dev Register a new fungible Polkadot token for an agent
function registerForeignToken(
bytes32 agentID,
address agent,
bytes32 tokenID,
string memory name,
string memory symbol,
uint8 decimals
) external {
AssetsStorage.Layout storage $ = AssetsStorage.layout();
if ($.tokenRegistryByID[tokenID].isRegistered == true) {
revert TokenAlreadyRegistered();
}
ERC20 foreignToken = new ERC20(agent, name, symbol, decimals);
address token = address(foreignToken);
TokenInfo memory info =
TokenInfo({isRegistered: true, isForeign: true, tokenID: tokenID, agentID: agentID, token: token});
$.tokenRegistry[token] = info;
$.tokenRegistryByID[tokenID] = info;
emit IGateway.ForeignTokenRegistered(tokenID, agentID, token);
}

// @dev Mint foreign token from Polkadot
function mintForeignToken(address executor, address agent, bytes32 tokenID, address recipient, uint256 amount)
external
{
address token = _tokenAddressOf(tokenID);
bytes memory call = abi.encodeCall(AgentExecutor.mintToken, (tokenID, token, recipient, amount));
(bool success,) = Agent(payable(agent)).invoke(executor, call);
if (!success) {
revert TokenMintFailed();
}
}

// @dev Get token address by tokenID
function tokenAddressOf(bytes32 tokenID) external view returns (address) {
return _tokenAddressOf(tokenID);
}

// @dev Get token address by tokenID
function _tokenAddressOf(bytes32 tokenID) internal view returns (address) {
AssetsStorage.Layout storage $ = AssetsStorage.layout();
if ($.tokenRegistryByID[tokenID].isRegistered == false) {
revert TokenNotRegistered();
}
return $.tokenRegistryByID[tokenID].token;
}
}
57 changes: 11 additions & 46 deletions contracts/src/Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ import {PricingStorage} from "./storage/PricingStorage.sol";
import {AssetsStorage} from "./storage/AssetsStorage.sol";

import {UD60x18, ud60x18, convert} from "prb/math/src/UD60x18.sol";
import {ERC20} from "./ERC20.sol";

contract Gateway is IGateway, IInitializable {
using Address for address;
Expand Down Expand Up @@ -91,7 +90,6 @@ contract Gateway is IGateway, IInitializable {
error InvalidConstructorParams();
error AlreadyInitialized();
error TokenNotRegistered();
error TokenAlreadyRegistered();

// handler functions are privileged
modifier onlySelf() {
Expand Down Expand Up @@ -283,9 +281,13 @@ contract Gateway is IGateway, IInitializable {
abi.decode(params.payload, (AgentExecuteCommand, bytes));

if (command == AgentExecuteCommand.RegisterToken) {
_registerForeignToken(params.agentID, agent, commandParams);
(bytes32 tokenID, string memory name, string memory symbol, uint8 decimals) =
abi.decode(commandParams, (bytes32, string, string, uint8));
Assets.registerForeignToken(params.agentID, agent, tokenID, name, symbol, decimals);
} else if (command == AgentExecuteCommand.MintToken) {
_mintForeignToken(agent, commandParams);
(bytes32 tokenID, address recipient, uint256 amount) =
abi.decode(commandParams, (bytes32, address, uint256));
Assets.mintForeignToken(AGENT_EXECUTOR, agent, tokenID, recipient, amount);
} else {
bytes memory call = abi.encodeCall(AgentExecutor.execute, (command, commandParams));
(bool success, bytes memory returndata) = Agent(payable(agent)).invoke(AGENT_EXECUTOR, call);
Expand Down Expand Up @@ -416,48 +418,6 @@ contract Gateway is IGateway, IInitializable {
emit PricingParametersChanged();
}

// @dev Register a new fungible Polkadot token for an agent
function _registerForeignToken(bytes32 agentID, address agent, bytes memory params) internal {
(bytes32 tokenID, string memory name, string memory symbol, uint8 decimals) =
abi.decode(params, (bytes32, string, string, uint8));
AssetsStorage.Layout storage $ = AssetsStorage.layout();
if ($.tokenRegistryByID[tokenID].isRegistered == true) {
revert TokenAlreadyRegistered();
}
ERC20 foreignToken = new ERC20(agent, name, symbol, decimals);
address token = address(foreignToken);
TokenInfo memory info =
TokenInfo({isRegistered: true, isForeign: true, tokenID: tokenID, agentID: agentID, token: token});
$.tokenRegistry[token] = info;
$.tokenRegistryByID[tokenID] = info;
emit ForeignTokenRegistered(tokenID, agentID, token);
}

// @dev Mint foreign token from Polkadot
function _mintForeignToken(address agent, bytes memory params) internal {
(bytes32 tokenID, address recipient, uint256 amount) = abi.decode(params, (bytes32, address, uint256));
address token = _tokenAddressOf(tokenID);
bytes memory call = abi.encodeCall(AgentExecutor.mintToken, (tokenID, token, recipient, amount));
(bool success, bytes memory returndata) = Agent(payable(agent)).invoke(AGENT_EXECUTOR, call);
if (!success) {
revert AgentExecutionFailed(returndata);
}
}

// @dev Get token address by tokenID
function tokenAddressOf(bytes32 tokenID) external view returns (address) {
return _tokenAddressOf(tokenID);
}

// @dev Get token address by tokenID
function _tokenAddressOf(bytes32 tokenID) internal view returns (address) {
AssetsStorage.Layout storage $ = AssetsStorage.layout();
if ($.tokenRegistryByID[tokenID].isRegistered == false) {
revert TokenNotRegistered();
}
return $.tokenRegistryByID[tokenID].token;
}

/**
* Assets
*/
Expand Down Expand Up @@ -519,6 +479,11 @@ contract Gateway is IGateway, IInitializable {
}
}

// @dev Get token address by tokenID
function tokenAddressOf(bytes32 tokenID) external view returns (address) {
return Assets.tokenAddressOf(tokenID);
}

/**
* Internal functions
*/
Expand Down

0 comments on commit 3da6be4

Please sign in to comment.