Skip to content

Commit

Permalink
Add tokens accounting
Browse files Browse the repository at this point in the history
  • Loading branch information
DimaStebaev committed Dec 13, 2024
1 parent e737c3c commit a164c19
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 32 deletions.
65 changes: 43 additions & 22 deletions contracts/schain/ExecutionLayer/ExecutionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ import "hardhat/console.sol";
import {AccessControlEnumerableUpgradeable}
from "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IExecutionManager, SchainHash} from "@skalenetwork/ima-interfaces/schain/ExecutionLayer/IExecutionManager.sol";
import {IMessageProxyForSchain} from "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol";
import {ITokenManagerERC20} from "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol";
import {ExecutorId} from "@skalenetwork/ima-interfaces/schain/ExecutionLayer/IExecutor.sol";
import {RoleRequired} from "../../CommonErrors.sol";
import {MetaActionId, Protocol} from "./Protocol.sol";
import {TokenManagerERC20} from "../TokenManagers/TokenManagerERC20.sol";
import {MetaActionId, Protocol, TokenInfo} from "./Protocol.sol";
import {Executor} from "./Executor.sol";

contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManager {
Expand All @@ -49,7 +51,7 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag

bytes32 public constant CONTROLLER_ROLE = keccak256("CONTROLLER_ROLE");

IMessageProxyForSchain public messageProxy;
TokenManagerERC20 public erc20TokenManager;
EnumerableMap.Bytes32ToAddressMap private _remoteExecutionManagers;
EnumerableMap.Bytes32ToAddressMap private _executors;
string public testMessage;
Expand Down Expand Up @@ -85,14 +87,14 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
}

modifier onlyMessageProxy() {
if (msg.sender != address(messageProxy)) {
if (msg.sender != erc20TokenManager.messageProxy.address) {
revert SenderIsNotMessageProxy(msg.sender);
}
_;
}

function initialize(IMessageProxyForSchain messageProxyAddress) external override initializer {
messageProxy = messageProxyAddress;
function initialize(ITokenManagerERC20 erc20TokenManagerAddress) external override initializer {
erc20TokenManager = TokenManagerERC20(address(erc20TokenManagerAddress));
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}

Expand All @@ -115,7 +117,7 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
}

function testSend(SchainHash targetChainHash, string calldata message) external override {
messageProxy.postOutgoingMessage(
erc20TokenManager.messageProxy().postOutgoingMessage(
targetChainHash,
address(_getRemoteExecutionManager(targetChainHash)),
abi.encode(message)
Expand Down Expand Up @@ -144,15 +146,18 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
}

function execute(
Protocol.MetaAction calldata metaAction
Protocol.MetaAction calldata metaAction,
TokenInfo[] calldata tokens
)
external
{
_processMetaAction(
_createMetaAction(
msg.sender,
metaAction
)
metaAction,
tokens
),
tokens
);
}

Expand Down Expand Up @@ -202,7 +207,8 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag

function _createMetaAction(
address sender,
Protocol.MetaAction memory metaAction
Protocol.MetaAction memory metaAction,
TokenInfo[] memory tokens
)
private
returns (MetaActionContainer storage metaActionContainer)
Expand All @@ -224,11 +230,13 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag

emit MetaActionCreated(id);

_pullTokensFromSender(sender, tokens);

return metaActions[id];
}

function _receiveMetaAction(Protocol.Message memory message, SchainHash sourceChain) private {
Protocol.MetaAction memory metaAction = Protocol.decodeMetaActionMessage(message);
(Protocol.MetaAction memory metaAction, TokenInfo[] memory tokens) = Protocol.decodeMetaActionMessage(message);
metaActions[message.metaActionId] = MetaActionContainer({
version: Protocol.VERSION,
sender: address(0),
Expand All @@ -237,7 +245,7 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
status: Protocol.MetaActionStatus.EXECUTING,
metaAction: metaAction
});
_processMetaAction(metaActions[message.metaActionId]);
_processMetaAction(metaActions[message.metaActionId], tokens);
}

function _processMessage(bytes memory encodedMessage, SchainHash sourceChain) private {
Expand All @@ -256,9 +264,9 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
}
}

function _processMetaAction(MetaActionContainer storage metaAction) private {
_executeActions(metaAction);
_sendNextMetaAction(metaAction);
function _processMetaAction(MetaActionContainer storage metaAction, TokenInfo[] memory tokens) private {
TokenInfo[] memory tokensAfterActions = _executeActions(metaAction, tokens);
_sendNextMetaAction(metaAction, tokensAfterActions);
}

function _processMetaActionConfirmation(MetaActionContainer storage metaAction) private {
Expand All @@ -272,22 +280,27 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
}
}

function _executeActions(MetaActionContainer storage metaAction) private {

function _executeActions(
MetaActionContainer storage metaAction,
TokenInfo[] memory tokens
)
private
returns (TokenInfo[] memory resultTokens)
{
}

function _postExecuteMetaAction(MetaActionContainer storage metaAction) private {

}

function _sendNextMetaAction(MetaActionContainer storage metaAction) private {
function _sendNextMetaAction(MetaActionContainer storage metaAction, TokenInfo[] memory tokens) private {
if (metaAction.metaAction.hasNextMetaAction()) {
Protocol.MetaAction memory nextMetaAction = Protocol.decodeMetaAction(metaAction.metaAction.nextMetaAction);
SchainHash targetChainHash = nextMetaAction.targetChainHash;
messageProxy.postOutgoingMessage(
erc20TokenManager.messageProxy().postOutgoingMessage(
targetChainHash,
address(_getRemoteExecutionManager(targetChainHash)),
Protocol.encodeMetaActionMessage(metaAction.id, nextMetaAction)
Protocol.encodeMetaActionMessage(metaAction.id, nextMetaAction, tokens)
);
} else {
_processMetaActionConfirmation(metaAction);
Expand All @@ -299,7 +312,7 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
Protocol.Confirmation memory confirmation = Protocol.Confirmation({
metaActionId: metaAction.id
});
messageProxy.postOutgoingMessage(
erc20TokenManager.messageProxy().postOutgoingMessage(
targetChainHash,
address(_getRemoteExecutionManager(targetChainHash)),
Protocol.encodeConfirmationMessage(metaAction.id, confirmation)
Expand All @@ -310,6 +323,14 @@ contract ExecutionManager is AccessControlEnumerableUpgradeable, IExecutionManag
return MetaActionId.wrap(keccak256(abi.encode(block.chainid, sender, nonces[sender]++)));
}

function _pullTokensFromSender(address sender, TokenInfo[] memory tokens) private {
uint256 tokensLength = tokens.length;
for (uint256 i = 0; i < tokensLength; ++i) {
IERC20 token = IERC20(tokens[i].token);
token.transferFrom(sender, address(this), tokens[i].number);
}
}

function _getRemoteExecutionManager(
SchainHash schainHash
)
Expand Down
23 changes: 19 additions & 4 deletions contracts/schain/ExecutionLayer/Protocol.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import "hardhat/console.sol";

import {SchainHash} from "@skalenetwork/ima-interfaces/schain/ExecutionLayer/IExecutionManager.sol";
import {ExecutorId} from "@skalenetwork/ima-interfaces/schain/ExecutionLayer/IExecutor.sol";
import {TokenInfo} from "@skalenetwork/ima-interfaces/schain/ExecutionLayer/IActionExecutor.sol";

type MetaActionId is bytes32;

Expand Down Expand Up @@ -96,23 +97,37 @@ library Protocol {
return abi.decode(encodedActions, (Action[]));
}

function encodeMetaActionMessage(MetaActionId id, MetaAction memory metaAction) internal pure returns (bytes memory message) {
function encodeMetaActionMessage(
MetaActionId id,
MetaAction memory metaAction,
TokenInfo[] memory tokens
)
internal
pure
returns (bytes memory message)
{
return abi.encode(Message({
version: VERSION,
messageType: MessageType.META_ACTION,
metaActionId: id,
payload: encodeMetaAction(metaAction)
payload: abi.encode(encodeMetaAction(metaAction), tokens)
}));
}

function decodeMetaActionMessage(Message memory message) internal pure returns (MetaAction memory metaAction) {
function decodeMetaActionMessage(
Message memory message
)
internal
pure
returns (MetaAction memory metaAction, TokenInfo[] memory tokens)
{
if (message.version != VERSION) {
revert IncompatibleVersion(message.version);
}
if (message.messageType != MessageType.META_ACTION) {
revert IncorrectMessageType(message.messageType, MessageType.META_ACTION);
}
return abi.decode(message.payload, (MetaAction));
return abi.decode(message.payload, (MetaAction, TokenInfo[]));
}

function encodeConfirmationMessage(MetaActionId id, Confirmation memory confirmation) internal pure returns (bytes memory encodedConfirmation) {
Expand Down
3 changes: 3 additions & 0 deletions contracts/schain/MessageProxyForSchain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol";
import {ITokenManagerERC20} from "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol";
import "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol";

import "../MessageProxy.sol";
Expand Down Expand Up @@ -112,6 +113,8 @@ contract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {
*/
uint256 public minimumReceiverBalance;

ITokenManagerERC20 public tokenManagerERC20;

/**
* @dev the event is emitted when value of receiver's minimum balance is changed
*/
Expand Down
2 changes: 1 addition & 1 deletion contracts/schain/TokenManagers/TokenManagerERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ contract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {
);
bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);
if (isMainChainToken) {
require(chainHash != MAINNET_HASH, "Main chain token could not be transfered to Mainnet");
require(chainHash != MAINNET_HASH, "Main chain token could not be transferred to Mainnet");
data = _receiveERC20(
chainHash,
address(contractOnSchain),
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@openzeppelin/hardhat-upgrades": "^3.1.1",
"@safe-global/api-kit": "2.5.4",
"@skalenetwork/etherbase-interfaces": "^0.0.1-develop.20",
"@skalenetwork/ima-interfaces": "^2.0.0-execution-layer.15",
"@skalenetwork/ima-interfaces": "^2.0.0-execution-layer.16",
"@skalenetwork/skale-manager-interfaces": "2.0.0",
"@skalenetwork/upgrade-tools": "3.0.0-develop.34",
"axios": "^0.21.4",
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1286,10 +1286,10 @@
resolved "https://registry.yarnpkg.com/@skalenetwork/etherbase-interfaces/-/etherbase-interfaces-0.0.1.tgz#97ed2069256a835efa1b088a58de17e2783a9e71"
integrity sha512-CgAo41sSL1KT9e1d3sUTxW5WPbEvHQwoqo3hLt+VW/6kGYukCuW4AHWMyDr5Jjw9KtjDKSOySDcoukhaeKxToQ==

"@skalenetwork/ima-interfaces@^2.0.0-execution-layer.15":
version "2.0.0-execution-layer.15"
resolved "https://registry.yarnpkg.com/@skalenetwork/ima-interfaces/-/ima-interfaces-2.0.0-execution-layer.15.tgz#4ff4fe8763929045ec1fed40810be57e01d84a21"
integrity sha512-kX/Pu6wAlv9JMwAi49bwrTsWcVacxUidHS7e18LYYM0GfeP0kDaGu1FzJ+cevhMa68eXlBn72Kph/FJjz5sPrw==
"@skalenetwork/ima-interfaces@^2.0.0-execution-layer.16":
version "2.0.0-execution-layer.16"
resolved "https://registry.yarnpkg.com/@skalenetwork/ima-interfaces/-/ima-interfaces-2.0.0-execution-layer.16.tgz#565eb08bc60e23ff73a67503c903d1ce5f874c9a"
integrity sha512-FHeePtJscmAToU4OKOB393GQ7y3/PbB3xxMzxAyxBtlIhubR5fnw20aSBatxLzWSGYkkGYBDincpOz/F9KbZhw==
dependencies:
"@skalenetwork/skale-manager-interfaces" "^3.2.0-develop.0"

Expand Down

0 comments on commit a164c19

Please sign in to comment.