Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add zeta handling to v2 contracts #214

Merged
merged 101 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
1f2625e
initialize gateway
lumtis Jun 18, 2024
bd71007
add receiver example
lumtis Jun 18, 2024
3553a8f
add test examples
lumtis Jun 18, 2024
791834b
add entry for test prototype
lumtis Jun 18, 2024
c1bd47d
typechain
lumtis Jun 18, 2024
6aed43c
change B to non-payable
lumtis Jun 18, 2024
8a973c1
generate
lumtis Jun 18, 2024
d562400
initialize custody contract
lumtis Jun 19, 2024
555ff9d
add execute with erc20 in gateway
lumtis Jun 19, 2024
21b8ace
add test
lumtis Jun 19, 2024
484096a
add some more tests
lumtis Jun 19, 2024
a0c8e5a
initalize uniswap test
lumtis Jun 19, 2024
5b893d2
finish test for uniswap
lumtis Jun 19, 2024
776caef
generate
lumtis Jun 19, 2024
704382b
use custom error
lumtis Jun 19, 2024
5e4766c
add some more comment
lumtis Jun 19, 2024
ce87491
a bit more comments
lumtis Jun 19, 2024
049f956
Merge branch 'main' into init-prototypes
skosito Jun 20, 2024
278c327
chore: change Gateway contract to be upgradable (#175)
skosito Jun 26, 2024
9303311
conflicts
lumtis Jun 27, 2024
cb0ca6c
fix yarn.lock
lumtis Jun 27, 2024
b9e5bfd
feat: inbound evm prototype (#178)
skosito Jun 27, 2024
9a785bc
feat: prototype inbound zevm (#183)
skosito Jul 1, 2024
430992a
feat: prototype outbound zevm (#191)
skosito Jul 1, 2024
a09cc0c
start worker script to deploy evm and zevm contracts on local hardhat…
skosito Jul 1, 2024
b39bc57
add simple script to deposit to gateway evm and listen to event in wo…
skosito Jul 1, 2024
4ee9023
Merge branch 'main' into init-prototypes
skosito Jul 1, 2024
d784b8e
Merge branch 'init-prototypes' into prototype-localnet
skosito Jul 1, 2024
7e3ad3e
fix coderabbit comments
skosito Jul 2, 2024
0b1f894
fix coderabbit comments
skosito Jul 2, 2024
7db93dd
fix yarn generate
skosito Jul 2, 2024
69d5763
Merge branch 'main' into init-prototypes
skosito Jul 2, 2024
022fee2
Merge branch 'init-prototypes' into prototype-localnet
skosito Jul 2, 2024
1e8af88
generate
skosito Jul 2, 2024
d94d8ff
renamings
skosito Jul 2, 2024
290a84e
add simple task to call receiver
skosito Jul 2, 2024
5817d9a
use receiver from call event in worker script
skosito Jul 2, 2024
f7d18fd
add zcontract localnet task
skosito Jul 2, 2024
51ff6a2
cleanup
skosito Jul 2, 2024
b857b9c
rename localnet script to worker
skosito Jul 2, 2024
cbd7dcf
run localnode and worker concurrently
skosito Jul 3, 2024
da9c0cd
different colors and prefix for node and worker
skosito Jul 3, 2024
6bd8c16
Merge branch 'main' into prototype-localnet
skosito Jul 3, 2024
f2a3371
fixes after merge
skosito Jul 3, 2024
cc93e3e
fixes after merge
skosito Jul 3, 2024
5a5f76b
fix tests
skosito Jul 3, 2024
941949e
fix worker after merge
skosito Jul 3, 2024
6275282
add more tasks
skosito Jul 3, 2024
8c33743
wait on hardhat node before starting worker
skosito Jul 3, 2024
fa96e30
remove redundant hardhat config
skosito Jul 3, 2024
b5a665a
generate
skosito Jul 3, 2024
badd4f8
add tasks to coderabbit
skosito Jul 3, 2024
d158c71
improve instructions
skosito Jul 3, 2024
49223b2
exclude in coderabbit
skosito Jul 3, 2024
4275805
test config changes
skosito Jul 3, 2024
caae687
revert
skosito Jul 3, 2024
0c1b370
add try catch
skosito Jul 3, 2024
76f284d
Merge branch 'main' into prototype-localnet
skosito Jul 3, 2024
e62b051
cleanup
skosito Jul 3, 2024
b69926f
add basic property based invariants for gateway evm
skosito Jul 3, 2024
bb27a54
PR comments
skosito Jul 4, 2024
d80596e
yarn generate
skosito Jul 4, 2024
e559c31
Merge branch 'prototype-localnet' into fuzz-tests-poc
skosito Jul 4, 2024
d0ad2f5
add simple assertion tests
skosito Jul 4, 2024
354e45a
move to test folder
skosito Jul 4, 2024
3190026
Merge branch 'main' into fuzz-tests-poc
skosito Jul 4, 2024
5524b59
add hardhat foundry and simple test
skosito Jul 8, 2024
4f1b2c2
bump hardhat
skosito Jul 8, 2024
86b4d77
yarn gen
skosito Jul 8, 2024
e881d7c
more foundry tests
skosito Jul 8, 2024
c4f89f8
generate
skosito Jul 8, 2024
4613a15
cleanup
skosito Jul 8, 2024
a9ff420
bump node version in ci
skosito Jul 9, 2024
c845f68
add foundry to ci test
skosito Jul 9, 2024
065c096
remappings
skosito Jul 9, 2024
4e3c0c3
submodules in ci test
skosito Jul 9, 2024
00a835b
fix workflows
skosito Jul 9, 2024
1925dd0
lint fix
skosito Jul 9, 2024
8e63c45
generate and readme
skosito Jul 9, 2024
01648d1
cleanup and improve test ci
skosito Jul 9, 2024
b8cc11b
add simple connector
skosito Jul 9, 2024
0e03d10
zeta withdraw zevm
skosito Jul 9, 2024
f3c9a0b
deposit and call gateway zevm
skosito Jul 10, 2024
8036d17
Merge branch 'main' into zeta-connector
skosito Jul 12, 2024
0df0624
Merge branch 'main' into zeta-connector
skosito Jul 13, 2024
8457ec3
cleanup
skosito Jul 16, 2024
4875824
generate
skosito Jul 16, 2024
399f318
fix
skosito Jul 16, 2024
6592586
Merge branch 'main' into zeta-connector
skosito Jul 17, 2024
65b25d3
fix after merge
skosito Jul 17, 2024
718787f
generate
skosito Jul 17, 2024
09e5d90
fix tests
skosito Jul 17, 2024
deee4d3
generate
skosito Jul 17, 2024
eb501de
Merge branch 'main' into zeta-connector
lumtis Jul 18, 2024
572646b
PR comments
skosito Jul 18, 2024
141bafe
generate
skosito Jul 18, 2024
a68698e
eth and non eth version of connector
skosito Jul 19, 2024
61d2c91
generate
skosito Jul 19, 2024
b4b0ce3
test fix
skosito Jul 19, 2024
6c50fae
Merge branch 'main' into zeta-connector
lumtis Jul 19, 2024
1cc8ad5
PR comments
skosito Jul 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/prototypes/evm/ERC20CustodyNew.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interfaces.sol";
import "./IGatewayEVM.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

Expand Down
79 changes: 64 additions & 15 deletions contracts/prototypes/evm/GatewayEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,44 @@
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "./interfaces.sol";

// The GatewayEVM contract is the endpoint to call smart contracts on external chains
// The contract doesn't hold any funds and should never have active allowances
import "./IGatewayEVM.sol";
import "./ZetaConnectorNewBase.sol";

/**
* @title GatewayEVM
* @notice The GatewayEVM contract is the endpoint to call smart contracts on external chains.
* @dev The contract doesn't hold any funds and should never have active allowances.
*/
contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGatewayEVMErrors, IGatewayEVMEvents {
using SafeERC20 for IERC20;

/// @notice The address of the custody contract.
address public custody;

/// @notice The address of the TSS (Threshold Signature Scheme) contract.
address public tssAddress;

/// @notice The address of the ZetaConnector contract.
address public zetaConnector;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have an issue to track adding the right comment to the contracts #204

But since we're starting to introduce many variables, this might make sense to try adding specs as we add the new variable?


/// @notice The address of the Zeta token contract.
address public zetaToken;

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}

function initialize(address _tssAddress) public initializer {
function initialize(address _tssAddress, address _zetaToken) public initializer {

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

__Ownable_init();
__UUPSUpgradeable_init();

if (_tssAddress == address(0)) revert ZeroAddress();
if (_tssAddress == address(0) || _zetaToken == address(0)) {
revert ZeroAddress();
}

tssAddress = _tssAddress;
zetaToken = _zetaToken;
}

function _authorizeUpgrade(address newImplementation) internal override onlyOwner() {}
Expand Down Expand Up @@ -59,7 +75,7 @@
address to,
uint256 amount,
bytes calldata data
) public returns (bytes memory) {
) public {
if (amount == 0) revert InsufficientETHAmount();
// Approve the target contract to spend the tokens
if(!resetApproval(token, to)) revert ApprovalFailed();
Expand All @@ -71,15 +87,13 @@
// Reset approval
if(!resetApproval(token, to)) revert ApprovalFailed();

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

emit ExecutedWithERC20(token, to, amount, data);

return result;
}

// Deposit ETH to tss
Expand All @@ -92,10 +106,11 @@
emit Deposit(msg.sender, receiver, msg.value, address(0), "");
}

// Deposit ERC20 tokens to custody
// Deposit ERC20 tokens to custody/connector
function deposit(address receiver, uint256 amount, address asset) external {
if (amount == 0) revert InsufficientERC20Amount();
IERC20(asset).safeTransferFrom(msg.sender, address(custody), amount);

transferFromToAssetHandler(msg.sender, asset, amount);

emit Deposit(msg.sender, receiver, amount, asset, "");
}
Expand All @@ -110,10 +125,11 @@
emit Deposit(msg.sender, receiver, msg.value, address(0), payload);
}

// Deposit ERC20 tokens to custody and call an omnichain smart contract
// Deposit ERC20 tokens to custody/connector and call an omnichain smart contract
function depositAndCall(address receiver, uint256 amount, address asset, bytes calldata payload) external {
if (amount == 0) revert InsufficientERC20Amount();
IERC20(asset).safeTransferFrom(msg.sender, address(custody), amount);

transferFromToAssetHandler(msg.sender, asset, amount);

emit Deposit(msg.sender, receiver, amount, asset, payload);
}
Expand All @@ -125,10 +141,43 @@

function setCustody(address _custody) external {
if (custody != address(0)) revert CustodyInitialized();
if (_custody == address(0)) revert ZeroAddress();

custody = _custody;
}

function setConnector(address _zetaConnector) external {
Dismissed Show dismissed Hide dismissed
if (zetaConnector != address(0)) revert CustodyInitialized();
if (_zetaConnector == address(0)) revert ZeroAddress();

zetaConnector = _zetaConnector;
}
Comment on lines +149 to +154
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New function to set zetaConnector.

The setConnector function allows setting the zetaConnector address. This function includes a check to ensure that zetaConnector is not already set, which is a good practice to prevent accidental overwrites. However, the parameter _zetaConnector should be in mixedCase to adhere to Solidity naming conventions.

- function setConnector(address _zetaConnector) external {
+ function setConnector(address zetaConnector) external {
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function setConnector(address _zetaConnector) external {
if (zetaConnector != address(0)) revert CustodyInitialized();
if (_zetaConnector == address(0)) revert ZeroAddress();
zetaConnector = _zetaConnector;
}
function setConnector(address zetaConnector) external {
if (zetaConnector != address(0)) revert CustodyInitialized();
if (zetaConnector == address(0)) revert ZeroAddress();
zetaConnector = zetaConnector;
}
Tools
GitHub Check: Slither

[warning] 152-152: Conformance to Solidity naming conventions
Parameter GatewayEVM.setConnector(address)._zetaConnector (contracts/prototypes/evm/GatewayEVM.sol#152) is not in mixedCase


function resetApproval(address token, address to) private returns (bool) {
return IERC20(token).approve(to, 0);
}

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)
IERC20(token).approve(zetaConnector, amount);
// send tokens to connector
ZetaConnectorNewBase(zetaConnector).receiveTokens(amount);
} else { // transfer to custody
IERC20(token).safeTransferFrom(from, custody, amount);
}
}
Comment on lines +160 to +171

Check warning

Code scanning / Slither

Unused return Medium


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)
IERC20(token).approve(zetaConnector, amount);
// send tokens to connector
ZetaConnectorNewBase(zetaConnector).receiveTokens(amount);
} else { // transfer to custody
IERC20(token).safeTransfer(custody, amount);
}
}
Comment on lines +173 to +182

Check warning

Code scanning / Slither

Unused return Medium

}
101 changes: 70 additions & 31 deletions contracts/prototypes/evm/GatewayEVMUpgradeTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,32 @@
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

import "./IGatewayEVM.sol";

// NOTE: Purpose of this contract is to test upgrade process, the only difference should be name of Executed event
// The Gateway contract is the endpoint to call smart contracts on external chains
// The contract doesn't hold any funds and should never have active allowances
/// @custom:oz-upgrades-from GatewayEVM
contract GatewayEVMUpgradeTest is Initializable, OwnableUpgradeable, UUPSUpgradeable {
contract GatewayEVMUpgradeTest is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGatewayEVMErrors, IGatewayEVMEvents {
using SafeERC20 for IERC20;

error ExecutionFailed();
error SendFailed();
error InsufficientETHAmount();
error ZeroAddress();
error ApprovalFailed();

address public custody;
address public tssAddress;
address public zetaConnector;
address public zetaToken;

event ExecutedV2(address indexed destination, uint256 value, bytes data);
event ExecutedWithERC20(address indexed token, address indexed to, uint256 amount, bytes data);
event SendERC20(bytes recipient, address indexed asset, uint256 amount);
event Send(bytes recipient, uint256 amount);

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
constructor() {}

function initialize(address _tssAddress) public initializer {
function initialize(address _tssAddress, address _zetaToken) public initializer {

Check notice

Code scanning / Slither

Missing zero address validation Low

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

__Ownable_init();
__UUPSUpgradeable_init();

if (_tssAddress == address(0)) revert ZeroAddress();

tssAddress = _tssAddress;
zetaToken = _zetaToken;
Comment on lines +27 to +34
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add zero address validation for _zetaToken.

The initialize function now accepts an address parameter _zetaToken and sets zetaToken to this value. However, it lacks a zero address validation for _zetaToken.

+       require(_zetaToken != address(0), "Zero address not allowed");
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function initialize(address _tssAddress, address _zetaToken) public initializer {
__Ownable_init();
__UUPSUpgradeable_init();
if (_tssAddress == address(0)) revert ZeroAddress();
tssAddress = _tssAddress;
zetaToken = _zetaToken;
function initialize(address _tssAddress, address _zetaToken) public initializer {
__Ownable_init();
__UUPSUpgradeable_init();
if (_tssAddress == address(0)) revert ZeroAddress();
require(_zetaToken != address(0), "Zero address not allowed");
tssAddress = _tssAddress;
zetaToken = _zetaToken;
Tools
GitHub Check: Slither

[notice] 27-27: Missing zero address validation
GatewayEVMUpgradeTest.initialize(address,address)._zetaToken (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#27) lacks a zero-check on :
- zetaToken = _zetaToken (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#34)


[warning] 27-27: Conformance to Solidity naming conventions
Parameter GatewayEVMUpgradeTest.initialize(address,address)._zetaToken (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#27) is not in mixedCase


[warning] 27-27: Conformance to Solidity naming conventions
Parameter GatewayEVMUpgradeTest.initialize(address,address)._tssAddress (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#27) is not in mixedCase

}

function _authorizeUpgrade(address newImplementation) internal override onlyOwner() {}
Expand Down Expand Up @@ -73,47 +64,95 @@
address to,
uint256 amount,
bytes calldata data
) external returns (bytes memory) {
) public returns (bytes memory) {
if (amount == 0) revert InsufficientETHAmount();
// Approve the target contract to spend the tokens
if(!IERC20(token).approve(to, 0)) revert ApprovalFailed();
if(!resetApproval(token, to)) revert ApprovalFailed();
if(!IERC20(token).approve(to, amount)) revert ApprovalFailed();

// Execute the call on the target contract
bytes memory result = _execute(to, data);

// Reset approval
if(!IERC20(token).approve(to, 0)) revert ApprovalFailed();
if(!resetApproval(token, to)) revert ApprovalFailed();

// Transfer any remaining tokens back to the custody contract
// Transfer any remaining tokens back to the custody/connector contract
uint256 remainingBalance = IERC20(token).balanceOf(address(this));
if (remainingBalance > 0) {
IERC20(token).safeTransfer(address(custody), remainingBalance);
address destination = address(custody);
if (token == zetaToken) {
destination = address(zetaConnector);
}
IERC20(token).safeTransfer(address(destination), remainingBalance);
}
Comment on lines +67 to 87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add executeWithERC20 function for ERC20 tokens.

The executeWithERC20 function handles the execution of calls with ERC20 token transfers. It includes setting and resetting approvals, which is crucial for security. Ensure that reentrancy guards are used to prevent potential vulnerabilities.

+    modifier nonReentrant() {
+        require(!locked, "Reentrant call");
+        locked = true;
+        _;
+        locked = false;
+    }

Committable suggestion was skipped due to low confidence.


emit ExecutedWithERC20(token, to, amount, data);

return result;
}

// Transfer specified token amount to ERC20Custody and emits event
function sendERC20(bytes calldata recipient, address token, uint256 amount) external {
IERC20(token).safeTransferFrom(msg.sender, address(custody), amount);
// Deposit ETH to tss
function deposit(address receiver) external payable {
if (msg.value == 0) revert InsufficientETHAmount();
(bool deposited, ) = tssAddress.call{value: msg.value}("");

emit SendERC20(recipient, token, amount);
if (deposited == false) revert DepositFailed();

emit Deposit(msg.sender, receiver, msg.value, address(0), "");
Comment on lines +94 to +101
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New function to deposit ETH.

This function allows for the deposit of ETH to a specified receiver. It includes checks for zero deposits and handles the actual transfer.

However, consider using high-level calls instead of low-level ones to improve security.

-        (bool deposited, ) = tssAddress.call{value: msg.value}("");
+        require(tssAddress.send(msg.value), "Deposit failed");
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Deposit ETH to tss
function deposit(address receiver) external payable {
if (msg.value == 0) revert InsufficientETHAmount();
(bool deposited, ) = tssAddress.call{value: msg.value}("");
emit SendERC20(recipient, token, amount);
if (deposited == false) revert DepositFailed();
emit Deposit(msg.sender, receiver, msg.value, address(0), "");
// Deposit ETH to tss
function deposit(address receiver) external payable {
if (msg.value == 0) revert InsufficientETHAmount();
require(tssAddress.send(msg.value), "Deposit failed");
emit Deposit(msg.sender, receiver, msg.value, address(0), "");

Comment on lines +95 to +101
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add deposit function for ETH.

The deposit function allows for the deposit of ETH to a specified receiver. It includes checks for zero deposits and handles the actual transfer. Consider using high-level calls instead of low-level ones to improve security.

-        (bool deposited, ) = tssAddress.call{value: msg.value}("");
+        require(tssAddress.send(msg.value), "Deposit failed");
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function deposit(address receiver) external payable {
if (msg.value == 0) revert InsufficientETHAmount();
(bool deposited, ) = tssAddress.call{value: msg.value}("");
emit SendERC20(recipient, token, amount);
if (deposited == false) revert DepositFailed();
emit Deposit(msg.sender, receiver, msg.value, address(0), "");
function deposit(address receiver) external payable {
if (msg.value == 0) revert InsufficientETHAmount();
require(tssAddress.send(msg.value), "Deposit failed");
emit Deposit(msg.sender, receiver, msg.value, address(0), "");
Tools
GitHub Check: Slither

[notice] 95-102: Reentrancy vulnerabilities
Reentrancy in GatewayEVMUpgradeTest.deposit(address) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#95-102):
External calls:
- (deposited,None) = tssAddress.call{value: msg.value}() (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#97)
Event emitted after the call(s):
- Deposit(msg.sender,receiver,msg.value,address(0),) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#101)


[warning] 95-102: Boolean equality
GatewayEVMUpgradeTest.deposit(address) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#95-102) compares to a boolean constant:
-deposited == false (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#99)


[warning] 95-102: Low-level calls
Low level call in GatewayEVMUpgradeTest.deposit(address) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#95-102):
- (deposited,None) = tssAddress.call{value: msg.value}() (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#97)

}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities Low

Check warning

Code scanning / Slither

Boolean equality Warning

Check warning

Code scanning / Slither

Low-level calls Warning


// Transfer specified ETH amount to TSS address and emits event
function send(bytes calldata recipient, uint256 amount) external payable {
// Deposit ERC20 tokens to custody
function deposit(address receiver, uint256 amount, address asset) external {
if (amount == 0) revert InsufficientERC20Amount();

address destination = address(custody);
if (asset == zetaToken) {
destination = address(zetaConnector);
}
IERC20(asset).safeTransferFrom(msg.sender, address(destination), amount);

emit Deposit(msg.sender, receiver, amount, asset, "");
}
Comment on lines +104 to +115
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add deposit function for ERC20 tokens.

The deposit function allows for the deposit of ERC20 tokens to a specified receiver. It includes checks for zero deposits and correct handling of the token transfer. Ensure that reentrancy guards are used to prevent potential vulnerabilities.

+    modifier nonReentrant() {
+        require(!locked, "Reentrant call");
+        locked = true;
+        _;
+        locked = false;
+    }

Committable suggestion was skipped due to low confidence.

Tools
GitHub Check: Slither

[notice] 105-115: Reentrancy vulnerabilities
Reentrancy in GatewayEVMUpgradeTest.deposit(address,uint256,address) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#105-115):
External calls:
- IERC20(asset).safeTransferFrom(msg.sender,address(destination),amount) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#112)
Event emitted after the call(s):
- Deposit(msg.sender,receiver,amount,asset,) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#114)


// Deposit ETH to tss and call an omnichain smart contract
function depositAndCall(address receiver, bytes calldata payload) external payable {
if (msg.value == 0) revert InsufficientETHAmount();
(bool deposited, ) = tssAddress.call{value: msg.value}("");

(bool sent, ) = tssAddress.call{value: msg.value}("");
if (deposited == false) revert DepositFailed();

emit Deposit(msg.sender, receiver, msg.value, address(0), payload);
}
Comment on lines +118 to +125

Check notice

Code scanning / Slither

Reentrancy vulnerabilities Low

Comment on lines +118 to +125

Check warning

Code scanning / Slither

Boolean equality Warning

Comment on lines +118 to +125

Check warning

Code scanning / Slither

Low-level calls Warning

Comment on lines +117 to +125
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add depositAndCall function for ETH.

The depositAndCall function allows for the deposit of ETH to a specified receiver and calling a contract on an external chain. Ensure that reentrancy guards are used to prevent potential vulnerabilities.

+    modifier nonReentrant() {
+        require(!locked, "Reentrant call");
+        locked = true;
+        _;
+        locked = false;
+    }

Committable suggestion was skipped due to low confidence.

Tools
GitHub Check: Slither

[notice] 118-125: Reentrancy vulnerabilities
Reentrancy in GatewayEVMUpgradeTest.depositAndCall(address,bytes) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#118-125):
External calls:
- (deposited,None) = tssAddress.call{value: msg.value}() (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#120)
Event emitted after the call(s):
- Deposit(msg.sender,receiver,msg.value,address(0),payload) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#124)


[warning] 118-125: Boolean equality
GatewayEVMUpgradeTest.depositAndCall(address,bytes) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#118-125) compares to a boolean constant:
-deposited == false (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#122)


[warning] 118-125: Low-level calls
Low level call in GatewayEVMUpgradeTest.depositAndCall(address,bytes) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#118-125):
- (deposited,None) = tssAddress.call{value: msg.value}() (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#120)


// Deposit ERC20 tokens to custody and call an omnichain smart contract
function depositAndCall(address receiver, uint256 amount, address asset, bytes calldata payload) external {
if (amount == 0) revert InsufficientERC20Amount();

address destination = address(custody);
if (asset == zetaToken) {
destination = address(zetaConnector);
}
IERC20(asset).safeTransferFrom(msg.sender, address(destination), amount);

if (sent == false) revert SendFailed();
emit Deposit(msg.sender, receiver, amount, asset, payload);
}
Comment on lines +127 to +138
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add depositAndCall function for ERC20 tokens.

The depositAndCall function allows for depositing ERC20 tokens and calling a contract on an external chain. Ensure that reentrancy guards are used to prevent potential vulnerabilities.

+    modifier nonReentrant() {
+        require(!locked, "Reentrant call");
+        locked = true;
+        _;
+        locked = false;
+    }

Committable suggestion was skipped due to low confidence.

Tools
GitHub Check: Slither

[notice] 128-138: Reentrancy vulnerabilities
Reentrancy in GatewayEVMUpgradeTest.depositAndCall(address,uint256,address,bytes) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#128-138):
External calls:
- IERC20(asset).safeTransferFrom(msg.sender,address(destination),amount) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#135)
Event emitted after the call(s):
- Deposit(msg.sender,receiver,amount,asset,payload) (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#137)


emit Send(recipient, msg.value);
// Call an omnichain smart contract without asset transfer
function call(address receiver, bytes calldata payload) external {
emit Call(msg.sender, receiver, payload);
}

function setCustody(address _custody) external {
if (custody != address(0)) revert CustodyInitialized();
custody = _custody;
}

function setConnector(address _zetaConnector) external {
Dismissed Show dismissed Hide dismissed

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

if (zetaConnector != address(0)) revert CustodyInitialized();
zetaConnector = _zetaConnector;
}
Comment on lines +150 to +153
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add zero address validation for _zetaConnector.

The setConnector function sets the zetaConnector. It includes a check to ensure that the connector is not already set, which is a good practice to prevent accidental overwrites. However, it lacks a zero address validation for _zetaConnector.

+        if (_zetaConnector == address(0)) revert ZeroAddress();
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function setConnector(address _zetaConnector) external {
if (zetaConnector != address(0)) revert CustodyInitialized();
zetaConnector = _zetaConnector;
}
function setConnector(address _zetaConnector) external {
if (zetaConnector != address(0)) revert CustodyInitialized();
if (_zetaConnector == address(0)) revert ZeroAddress();
zetaConnector = _zetaConnector;
}
Tools
GitHub Check: Slither

[warning] 150-150: Conformance to Solidity naming conventions
Parameter GatewayEVMUpgradeTest.setConnector(address)._zetaConnector (contracts/prototypes/evm/GatewayEVMUpgradeTest.sol#150) is not in mixedCase


function resetApproval(address token, address to) private returns (bool) {
return IERC20(token).approve(to, 0);
}
}

Check warning

Code scanning / Slither

Missing inheritance Warning

GatewayEVMUpgradeTest should inherit from IGatewayEVM
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,13 @@ interface IGatewayEVMErrors {
error CustodyInitialized();
}

interface IReceiverEVMEvents {
event ReceivedPayable(address sender, uint256 value, string str, uint256 num, bool flag);
event ReceivedNonPayable(address sender, string[] strs, uint256[] nums, bool flag);
event ReceivedERC20(address sender, uint256 amount, address token, address destination);
event ReceivedNoParams(address sender);
}

interface IGatewayEVM {
function executeWithERC20(
address token,
address to,
uint256 amount,
bytes calldata data
) external returns (bytes memory);
) external;

function execute(address destination, bytes calldata data) external payable returns (bytes memory);
}
9 changes: 9 additions & 0 deletions contracts/prototypes/evm/IReceiverEVM.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IReceiverEVMEvents {
event ReceivedPayable(address sender, uint256 value, string str, uint256 num, bool flag);
event ReceivedNonPayable(address sender, string[] strs, uint256[] nums, bool flag);
event ReceivedERC20(address sender, uint256 amount, address token, address destination);
event ReceivedNoParams(address sender);
}
13 changes: 13 additions & 0 deletions contracts/prototypes/evm/IZetaNonEthNew.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
* @dev IZetaNonEthNew is a mintable / burnable version of IERC20
*/
interface IZetaNonEthNew is IERC20 {
function burnFrom(address account, uint256 amount) external;

function mint(address mintee, uint256 value, bytes32 internalSendHash) external;
}
Loading
Loading