Skip to content

Commit

Permalink
feat: ERC20Custody and ZetaConnector uups upgradable (#385)
Browse files Browse the repository at this point in the history
  • Loading branch information
skosito authored Oct 14, 2024
1 parent 475acfa commit 282fdaa
Show file tree
Hide file tree
Showing 102 changed files with 25,193 additions and 13,043 deletions.
34 changes: 27 additions & 7 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,12 +43,18 @@ 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_);
Expand All @@ -48,6 +64,10 @@ contract ERC20Custody is IERC20Custody, ReentrancyGuard, AccessControl, Pausable
_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 Down
44 changes: 36 additions & 8 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 @@ -50,6 +74,10 @@ abstract contract ZetaConnectorBase is IZetaConnectorEvents, ReentrancyGuard, Pa
_grantRole(PAUSER_ROLE, admin_);
}

/// @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 Down
10 changes: 7 additions & 3 deletions v2/contracts/evm/ZetaConnectorNative.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract ZetaConnectorNative is ZetaConnectorBase {
using SafeERC20 for IERC20;

constructor(
function initialize(
address gateway_,
address zetaToken_,
address tssAddress_,
address admin_
)
ZetaConnectorBase(gateway_, zetaToken_, tssAddress_, admin_)
{ }
public
override
initializer
{
super.initialize(gateway_, zetaToken_, tssAddress_, admin_);
}

/// @notice Withdraw tokens to a specified address.
/// @param to The address to withdraw tokens to.
Expand Down
18 changes: 12 additions & 6 deletions v2/contracts/evm/ZetaConnectorNonNative.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,29 @@ import "./interfaces/IZetaNonEthNew.sol";
/// @notice Implementation of ZetaConnectorBase for non-native token handling.
/// @dev This contract mints and burns Zeta tokens and interacts with the Gateway contract.
contract ZetaConnectorNonNative is ZetaConnectorBase {
/// @notice Max supply for minting.
uint256 public maxSupply = type(uint256).max;

/// @notice Event triggered when max supply is updated.
/// @param maxSupply New max supply.
event MaxSupplyUpdated(uint256 maxSupply);

error ExceedsMaxSupply();

constructor(
/// @notice Max supply for minting.
uint256 public maxSupply;

function initialize(
address gateway_,
address zetaToken_,
address tssAddress_,
address admin_
)
ZetaConnectorBase(gateway_, zetaToken_, tssAddress_, admin_)
{ }
public
override
initializer
{
super.initialize(gateway_, zetaToken_, tssAddress_, admin_);

maxSupply = type(uint256).max;
}

/// @notice Set max supply for minting.
/// @param maxSupply_ New max supply.
Expand Down
2 changes: 1 addition & 1 deletion v2/docs/src/contracts/Revert.sol/interface.Revertable.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Revertable
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/dedf2ca4d335fe85937fd686450fecebb5456bc9/contracts/Revert.sol)
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/ec2fd2afc191922ecd1aea1903a837977ec7967e/contracts/Revert.sol)

Interface for contracts that support revertable calls.

Expand Down
2 changes: 1 addition & 1 deletion v2/docs/src/contracts/Revert.sol/struct.RevertContext.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RevertContext
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/dedf2ca4d335fe85937fd686450fecebb5456bc9/contracts/Revert.sol)
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/ec2fd2afc191922ecd1aea1903a837977ec7967e/contracts/Revert.sol)

Struct containing revert context passed to onRevert.

Expand Down
2 changes: 1 addition & 1 deletion v2/docs/src/contracts/Revert.sol/struct.RevertOptions.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RevertOptions
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/dedf2ca4d335fe85937fd686450fecebb5456bc9/contracts/Revert.sol)
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/ec2fd2afc191922ecd1aea1903a837977ec7967e/contracts/Revert.sol)

Struct containing revert options

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# ERC20Custody
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/dedf2ca4d335fe85937fd686450fecebb5456bc9/contracts/evm/ERC20Custody.sol)
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/ec2fd2afc191922ecd1aea1903a837977ec7967e/contracts/evm/ERC20Custody.sol)

**Inherits:**
[IERC20Custody](/contracts/evm/interfaces/IERC20Custody.sol/interface.IERC20Custody.md), ReentrancyGuard, AccessControl, Pausable
Initializable, UUPSUpgradeable, [IERC20Custody](/contracts/evm/interfaces/IERC20Custody.sol/interface.IERC20Custody.md), ReentrancyGuardUpgradeable, AccessControlUpgradeable, PausableUpgradeable

Holds the ERC20 tokens deposited on ZetaChain and includes functionality to call a contract.

Expand All @@ -15,7 +15,7 @@ Gateway contract.


```solidity
IGatewayEVM public immutable gateway;
IGatewayEVM public gateway;
```


Expand Down Expand Up @@ -74,17 +74,32 @@ bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE");


## Functions
### constructor
### initialize

Constructor for ERC20Custody.
Initializer for ERC20Custody.

*Set admin as default admin and pauser, and tssAddress as tss role.*


```solidity
constructor(address gateway_, address tssAddress_, address admin_);
function initialize(address gateway_, address tssAddress_, address admin_) public initializer;
```

### _authorizeUpgrade

*Authorizes the upgrade of the contract, sender must be owner.*


```solidity
function _authorizeUpgrade(address newImplementation) internal override onlyRole(DEFAULT_ADMIN_ROLE);
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`newImplementation`|`address`|Address of the new implementation.|


### pause

Pause contract.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# GatewayEVM
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/dedf2ca4d335fe85937fd686450fecebb5456bc9/contracts/evm/GatewayEVM.sol)
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/ec2fd2afc191922ecd1aea1903a837977ec7967e/contracts/evm/GatewayEVM.sol)

**Inherits:**
Initializable, AccessControlUpgradeable, UUPSUpgradeable, [IGatewayEVM](/contracts/evm/interfaces/IGatewayEVM.sol/interface.IGatewayEVM.md), ReentrancyGuardUpgradeable, PausableUpgradeable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# ZetaConnectorBase
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/dedf2ca4d335fe85937fd686450fecebb5456bc9/contracts/evm/ZetaConnectorBase.sol)
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/ec2fd2afc191922ecd1aea1903a837977ec7967e/contracts/evm/ZetaConnectorBase.sol)

**Inherits:**
[IZetaConnectorEvents](/contracts/evm/interfaces/IZetaConnector.sol/interface.IZetaConnectorEvents.md), ReentrancyGuard, Pausable, AccessControl
Initializable, UUPSUpgradeable, [IZetaConnectorEvents](/contracts/evm/interfaces/IZetaConnector.sol/interface.IZetaConnectorEvents.md), ReentrancyGuardUpgradeable, PausableUpgradeable, AccessControlUpgradeable

Abstract base contract for ZetaConnector.

Expand All @@ -15,7 +15,7 @@ The Gateway contract used for executing cross-chain calls.


```solidity
IGatewayEVM public immutable gateway;
IGatewayEVM public gateway;
```


Expand All @@ -24,7 +24,7 @@ The address of the Zeta token.


```solidity
address public immutable zetaToken;
address public zetaToken;
```


Expand Down Expand Up @@ -65,16 +65,39 @@ bytes32 public constant TSS_ROLE = keccak256("TSS_ROLE");


## Functions
### constructor
### initialize

Constructor for ZetaConnectors.
Initializer for ZetaConnectors.

*Set admin as default admin and pauser, and tssAddress as tss role.*


```solidity
constructor(address gateway_, address zetaToken_, address tssAddress_, address admin_);
function initialize(
address gateway_,
address zetaToken_,
address tssAddress_,
address admin_
)
public
virtual
initializer;
```

### _authorizeUpgrade

*Authorizes the upgrade of the contract, sender must be owner.*


```solidity
function _authorizeUpgrade(address newImplementation) internal override onlyRole(DEFAULT_ADMIN_ROLE);
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`newImplementation`|`address`|Address of the new implementation.|


### updateTSSAddress

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ZetaConnectorNative
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/dedf2ca4d335fe85937fd686450fecebb5456bc9/contracts/evm/ZetaConnectorNative.sol)
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/ec2fd2afc191922ecd1aea1903a837977ec7967e/contracts/evm/ZetaConnectorNative.sol)

**Inherits:**
[ZetaConnectorBase](/contracts/evm/ZetaConnectorBase.sol/abstract.ZetaConnectorBase.md)
Expand All @@ -10,17 +10,19 @@ Implementation of ZetaConnectorBase for native token handling.


## Functions
### constructor
### initialize


```solidity
constructor(
function initialize(
address gateway_,
address zetaToken_,
address tssAddress_,
address admin_
)
ZetaConnectorBase(gateway_, zetaToken_, tssAddress_, admin_);
public
override
initializer;
```

### withdraw
Expand Down
Loading

0 comments on commit 282fdaa

Please sign in to comment.