Skip to content

Commit

Permalink
Merge branch 'main' into generate-addresses-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
fadeev committed Oct 17, 2024
2 parents 1ea2a5e + db2f95f commit 09c9415
Show file tree
Hide file tree
Showing 146 changed files with 26,654 additions and 15,050 deletions.
1 change: 1 addition & 0 deletions v1/data/addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,4 @@
}
}
}

1 change: 1 addition & 0 deletions v1/data/addresses.mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -421,3 +421,4 @@
"type": "tss"
}
]

1 change: 0 additions & 1 deletion v1/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,4 @@ const config: HardhatUserConfig = {
],
},
};

export default config;
5 changes: 1 addition & 4 deletions v1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,5 @@
"tsc:watch": "npx tsc --watch"
},
"types": "./dist/lib/index.d.ts",
"version": "0.0.8",
"dependencies": {
"chokidar": "^4.0.1"
}
"version": "0.0.8"
}
8 changes: 8 additions & 0 deletions v2/contracts/Errors.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

/// @title INotSupportedMethods
/// @notice Interface for contracts that with non supported methods.
interface INotSupportedMethods {
error ZETANotSupported();
}
39 changes: 30 additions & 9 deletions v2/contracts/evm/ERC20Custody.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,30 @@ import { IGatewayEVM } from "./interfaces/IGatewayEVM.sol";

import { RevertContext } from "../../contracts/Revert.sol";

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

/// @title ERC20Custody
/// @notice Holds the ERC20 tokens deposited on ZetaChain and includes functionality to call a contract.
/// @dev This contract does not call smart contracts directly, it passes through the Gateway contract.
contract ERC20Custody is IERC20Custody, ReentrancyGuard, AccessControl, Pausable {
contract ERC20Custody is
Initializable,
UUPSUpgradeable,
IERC20Custody,
ReentrancyGuardUpgradeable,
AccessControlUpgradeable,
PausableUpgradeable
{
using SafeERC20 for IERC20;

/// @notice Gateway contract.
IGatewayEVM public immutable gateway;
IGatewayEVM public gateway;
/// @notice Mapping of whitelisted tokens => true/false.
mapping(address => bool) public whitelisted;
/// @notice The address of the TSS (Threshold Signature Scheme) contract.
Expand All @@ -33,21 +43,32 @@ contract ERC20Custody is IERC20Custody, ReentrancyGuard, AccessControl, Pausable
/// @notice New role identifier for whitelister role.
bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE");

/// @notice Constructor for ERC20Custody.
/// @notice Initializer for ERC20Custody.
/// @dev Set admin as default admin and pauser, and tssAddress as tss role.
constructor(address gateway_, address tssAddress_, address admin_) {
function initialize(address gateway_, address tssAddress_, address admin_) public initializer {
if (gateway_ == address(0) || tssAddress_ == address(0) || admin_ == address(0)) {
revert ZeroAddress();
}

__UUPSUpgradeable_init();
__ReentrancyGuard_init();
__AccessControl_init();
__Pausable_init();

gateway = IGatewayEVM(gateway_);
tssAddress = tssAddress_;
_grantRole(DEFAULT_ADMIN_ROLE, admin_);
_grantRole(PAUSER_ROLE, admin_);
_grantRole(PAUSER_ROLE, tssAddress_);
_grantRole(WITHDRAWER_ROLE, tssAddress_);
_grantRole(WHITELISTER_ROLE, admin_);
_grantRole(WHITELISTER_ROLE, tssAddress_);
}

/// @dev Authorizes the upgrade of the contract, sender must be owner.
/// @param newImplementation Address of the new implementation.
function _authorizeUpgrade(address newImplementation) internal override onlyRole(DEFAULT_ADMIN_ROLE) { }

/// @notice Pause contract.
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
Expand All @@ -69,9 +90,9 @@ contract ERC20Custody is IERC20Custody, ReentrancyGuard, AccessControl, Pausable
_grantRole(WITHDRAWER_ROLE, newTSSAddress);
_grantRole(WHITELISTER_ROLE, newTSSAddress);

tssAddress = newTSSAddress;
emit UpdatedCustodyTSSAddress(tssAddress, newTSSAddress);

emit UpdatedCustodyTSSAddress(newTSSAddress);
tssAddress = newTSSAddress;
}

/// @notice Unpause contract.
Expand Down
56 changes: 33 additions & 23 deletions v2/contracts/evm/GatewayEVM.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import { INotSupportedMethods } from "../../contracts/Errors.sol";
import { RevertContext, RevertOptions, Revertable } from "../../contracts/Revert.sol";
import { ZetaConnectorBase } from "./ZetaConnectorBase.sol";
import { IERC20Custody } from "./interfaces/IERC20Custody.sol";
Expand All @@ -23,7 +24,8 @@ contract GatewayEVM is
UUPSUpgradeable,
IGatewayEVM,
ReentrancyGuardUpgradeable,
PausableUpgradeable
PausableUpgradeable,
INotSupportedMethods
{
using SafeERC20 for IERC20;

Expand Down Expand Up @@ -63,6 +65,7 @@ contract GatewayEVM is

_grantRole(DEFAULT_ADMIN_ROLE, admin_);
_grantRole(PAUSER_ROLE, admin_);
_grantRole(PAUSER_ROLE, tssAddress_);
tssAddress = tssAddress_;
_grantRole(TSS_ROLE, tssAddress_);

Expand All @@ -81,9 +84,9 @@ contract GatewayEVM is
_revokeRole(TSS_ROLE, tssAddress);
_grantRole(TSS_ROLE, newTSSAddress);

tssAddress = newTSSAddress;
emit UpdatedGatewayTSSAddress(tssAddress, newTSSAddress);

emit UpdatedGatewayTSSAddress(newTSSAddress);
tssAddress = newTSSAddress;
}

/// @notice Pause contract.
Expand Down Expand Up @@ -190,18 +193,18 @@ contract GatewayEVM is
if (amount == 0) revert InsufficientERC20Amount();
if (to == address(0)) revert ZeroAddress();
// Approve the target contract to spend the tokens
if (!resetApproval(token, to)) revert ApprovalFailed();
if (!_resetApproval(token, to)) revert ApprovalFailed();
if (!IERC20(token).approve(to, amount)) revert ApprovalFailed();
// Execute the call on the target contract
_executeArbitraryCall(to, data);

// Reset approval
if (!resetApproval(token, to)) revert ApprovalFailed();
if (!_resetApproval(token, to)) revert ApprovalFailed();

// Transfer any remaining tokens back to the custody/connector contract
uint256 remainingBalance = IERC20(token).balanceOf(address(this));
if (remainingBalance > 0) {
transferToAssetHandler(token, remainingBalance);
_transferToAssetHandler(token, remainingBalance);
}

emit ExecutedWithERC20(token, to, amount, data);
Expand Down Expand Up @@ -249,6 +252,7 @@ contract GatewayEVM is
{
if (msg.value == 0) revert InsufficientETHAmount();
if (receiver == address(0)) revert ZeroAddress();
if (revertOptions.revertMessage.length > MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();

(bool deposited,) = tssAddress.call{ value: msg.value }("");

Expand All @@ -274,8 +278,9 @@ contract GatewayEVM is
{
if (amount == 0) revert InsufficientERC20Amount();
if (receiver == address(0)) revert ZeroAddress();
if (revertOptions.revertMessage.length > MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();

transferFromToAssetHandler(msg.sender, asset, amount);
_transferFromToAssetHandler(msg.sender, asset, amount);

emit Deposited(msg.sender, receiver, amount, asset, "", revertOptions);
}
Expand All @@ -296,7 +301,7 @@ contract GatewayEVM is
{
if (msg.value == 0) revert InsufficientETHAmount();
if (receiver == address(0)) revert ZeroAddress();
if (payload.length + revertOptions.revertMessage.length >= MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();
if (payload.length + revertOptions.revertMessage.length > MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();

(bool deposited,) = tssAddress.call{ value: msg.value }("");

Expand Down Expand Up @@ -324,9 +329,9 @@ contract GatewayEVM is
{
if (amount == 0) revert InsufficientERC20Amount();
if (receiver == address(0)) revert ZeroAddress();
if (payload.length + revertOptions.revertMessage.length >= MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();
if (payload.length + revertOptions.revertMessage.length > MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();

transferFromToAssetHandler(msg.sender, asset, amount);
_transferFromToAssetHandler(msg.sender, asset, amount);

emit Deposited(msg.sender, receiver, amount, asset, payload, revertOptions);
}
Expand All @@ -345,7 +350,7 @@ contract GatewayEVM is
nonReentrant
{
if (receiver == address(0)) revert ZeroAddress();
if (payload.length + revertOptions.revertMessage.length >= MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();
if (payload.length + revertOptions.revertMessage.length > MAX_PAYLOAD_SIZE) revert PayloadSizeExceeded();

emit Called(msg.sender, receiver, payload, revertOptions);
}
Expand Down Expand Up @@ -375,7 +380,7 @@ contract GatewayEVM is
/// @param token Address of the ERC20 token.
/// @param to Address to reset the approval for.
/// @return True if the approval reset was successful, false otherwise.
function resetApproval(address token, address to) private returns (bool) {
function _resetApproval(address token, address to) private returns (bool) {
return IERC20(token).approve(to, 0);
}

Expand All @@ -385,15 +390,20 @@ contract GatewayEVM is
/// @param from Address of the sender.
/// @param token Address of the ERC20 token.
/// @param amount Amount of tokens to transfer.
function transferFromToAssetHandler(address from, address token, uint256 amount) private {
function _transferFromToAssetHandler(address from, address token, uint256 amount) private {
if (token == zetaToken) {
// transfer to connector
// transfer amount to gateway
IERC20(token).safeTransferFrom(from, address(this), amount);
// approve connector to handle tokens depending on connector version (eg. lock or burn)
if (!IERC20(token).approve(zetaConnector, amount)) revert ApprovalFailed();
// send tokens to connector
ZetaConnectorBase(zetaConnector).receiveTokens(amount);
// TODO: remove error and comment out code once ZETA supported back
// https://github.com/zeta-chain/protocol-contracts/issues/394
// ZETA token is currently not supported for deposit
revert ZETANotSupported();

// // transfer to connector
// // transfer amount to gateway
// IERC20(token).safeTransferFrom(from, address(this), amount);
// // approve connector to handle tokens depending on connector version (eg. lock or burn)
// if (!IERC20(token).approve(zetaConnector, amount)) revert ApprovalFailed();
// // send tokens to connector
// ZetaConnectorBase(zetaConnector).receiveTokens(amount);
} else {
// transfer to custody
if (!IERC20Custody(custody).whitelisted(token)) revert NotWhitelistedInCustody();
Expand All @@ -406,7 +416,7 @@ contract GatewayEVM is
/// type.
/// @param token Address of the ERC20 token.
/// @param amount Amount of tokens to transfer.
function transferToAssetHandler(address token, uint256 amount) private {
function _transferToAssetHandler(address token, uint256 amount) private {
if (token == zetaToken) {
// transfer to connector
// approve connector to handle tokens depending on connector version (eg. lock or burn)
Expand All @@ -425,7 +435,7 @@ contract GatewayEVM is
/// @param data Calldata to pass to the call.
/// @return The result of the call.
function _executeArbitraryCall(address destination, bytes calldata data) private returns (bytes memory) {
revertIfOnCallOrOnRevert(data);
_revertIfOnCallOrOnRevert(data);
(bool success, bytes memory result) = destination.call{ value: msg.value }(data);
if (!success) revert ExecutionFailed();

Expand All @@ -449,7 +459,7 @@ contract GatewayEVM is
}

// @dev prevent spoofing onCall and onRevert functions
function revertIfOnCallOrOnRevert(bytes calldata data) private pure {
function _revertIfOnCallOrOnRevert(bytes calldata data) private pure {
if (data.length >= 4) {
bytes4 functionSelector;
assembly {
Expand Down
49 changes: 39 additions & 10 deletions v2/contracts/evm/ZetaConnectorBase.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

import { RevertContext } from "../../contracts/Revert.sol";
import { IGatewayEVM, IGatewayEVMErrors, IGatewayEVMEvents } from "../../contracts/evm/interfaces/IGatewayEVM.sol";
Expand All @@ -14,16 +16,23 @@ import "../../contracts/evm/interfaces/IZetaConnector.sol";
/// @title ZetaConnectorBase
/// @notice Abstract base contract for ZetaConnector.
/// @dev This contract implements basic functionality for handling tokens and interacting with the Gateway contract.
abstract contract ZetaConnectorBase is IZetaConnectorEvents, ReentrancyGuard, Pausable, AccessControl {
abstract contract ZetaConnectorBase is
Initializable,
UUPSUpgradeable,
IZetaConnectorEvents,
ReentrancyGuardUpgradeable,
PausableUpgradeable,
AccessControlUpgradeable
{
using SafeERC20 for IERC20;

/// @notice Error indicating that a zero address was provided.
error ZeroAddress();

/// @notice The Gateway contract used for executing cross-chain calls.
IGatewayEVM public immutable gateway;
IGatewayEVM public gateway;
/// @notice The address of the Zeta token.
address public immutable zetaToken;
address public zetaToken;
/// @notice The address of the TSS (Threshold Signature Scheme) contract.
address public tssAddress;

Expand All @@ -34,12 +43,27 @@ abstract contract ZetaConnectorBase is IZetaConnectorEvents, ReentrancyGuard, Pa
/// @notice New role identifier for tss role.
bytes32 public constant TSS_ROLE = keccak256("TSS_ROLE");

/// @notice Constructor for ZetaConnectors.
/// @notice Initializer for ZetaConnectors.
/// @dev Set admin as default admin and pauser, and tssAddress as tss role.
constructor(address gateway_, address zetaToken_, address tssAddress_, address admin_) {
function initialize(
address gateway_,
address zetaToken_,
address tssAddress_,
address admin_
)
public
virtual
initializer
{
if (gateway_ == address(0) || zetaToken_ == address(0) || tssAddress_ == address(0) || admin_ == address(0)) {
revert ZeroAddress();
}

__UUPSUpgradeable_init();
__ReentrancyGuard_init();
__AccessControl_init();
__Pausable_init();

gateway = IGatewayEVM(gateway_);
zetaToken = zetaToken_;
tssAddress = tssAddress_;
Expand All @@ -48,8 +72,13 @@ abstract contract ZetaConnectorBase is IZetaConnectorEvents, ReentrancyGuard, Pa
_grantRole(WITHDRAWER_ROLE, tssAddress_);
_grantRole(TSS_ROLE, tssAddress_);
_grantRole(PAUSER_ROLE, admin_);
_grantRole(PAUSER_ROLE, tssAddress_);
}

/// @dev Authorizes the upgrade of the contract, sender must be owner.
/// @param newImplementation Address of the new implementation.
function _authorizeUpgrade(address newImplementation) internal override onlyRole(DEFAULT_ADMIN_ROLE) { }

/// @notice Update tss address
/// @param newTSSAddress new tss address
function updateTSSAddress(address newTSSAddress) external onlyRole(DEFAULT_ADMIN_ROLE) {
Expand All @@ -61,9 +90,9 @@ abstract contract ZetaConnectorBase is IZetaConnectorEvents, ReentrancyGuard, Pa
_grantRole(WITHDRAWER_ROLE, newTSSAddress);
_grantRole(TSS_ROLE, newTSSAddress);

tssAddress = newTSSAddress;
emit UpdatedZetaConnectorTSSAddress(tssAddress, newTSSAddress);

emit UpdatedZetaConnectorTSSAddress(newTSSAddress);
tssAddress = newTSSAddress;
}

/// @notice Pause contract.
Expand Down
Loading

0 comments on commit 09c9415

Please sign in to comment.