-
Notifications
You must be signed in to change notification settings - Fork 59
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: v2 contracts natspec #249
Changes from all commits
5b5cc4b
f1cf789
8b9669e
1851b89
ba0f25f
3f4990c
a686f66
58160e8
63bfb60
0837639
f3f9dfa
a3719f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,14 +7,13 @@ | |
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; | ||
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; | ||
|
||
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. | ||
*/ | ||
/// @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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Should we open an issue to implement this logic specifically?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is receive for ERC777? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets open issue, i also think we would need check if sender is tss and dont revert in that case? but receiving eth/erc20 cant cause issues right? |
||
contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGatewayEVMErrors, IGatewayEVMEvents, ReentrancyGuardUpgradeable { | ||
using SafeERC20 for IERC20; | ||
|
||
|
@@ -27,15 +26,15 @@ | |
/// @notice The address of the Zeta token contract. | ||
address public zetaToken; | ||
|
||
// @dev Only TSS address allowed modifier. | ||
/// @notice Only TSS address allowed modifier. | ||
modifier onlyTSS() { | ||
if (msg.sender != tssAddress) { | ||
revert InvalidSender(); | ||
} | ||
_; | ||
} | ||
|
||
// @dev Only asset handler (custody, connector) allowed modifier. | ||
/// @notice Only custody or connector address allowed modifier. | ||
modifier onlyAssetHandler() { | ||
if (msg.sender != custody && msg.sender != zetaConnector) { | ||
revert InvalidSender(); | ||
|
@@ -61,17 +60,25 @@ | |
zetaToken = _zetaToken; | ||
} | ||
|
||
/// @dev Authorizes the upgrade of the contract, sender must be owner. | ||
/// @param newImplementation Address of the new implementation. | ||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner() {} | ||
|
||
/// @dev Internal function to execute a call to a destination address. | ||
/// @param destination Address to call. | ||
/// @param data Calldata to pass to the call. | ||
/// @return The result of the call. | ||
function _execute(address destination, bytes calldata data) internal returns (bytes memory) { | ||
(bool success, bytes memory result) = destination.call{value: msg.value}(data); | ||
if (!success) revert ExecutionFailed(); | ||
|
||
return result; | ||
} | ||
|
||
// Called by the TSS | ||
// Calling onRevert directly | ||
/// @notice Transfers msg.value to destination contract and executes it's onRevert function. | ||
/// @dev This function can only be called by the TSS address and it is payable. | ||
/// @param destination Address to call. | ||
/// @param data Calldata to pass to the call. | ||
function executeRevert(address destination, bytes calldata data) public payable onlyTSS { | ||
(bool success, bytes memory result) = destination.call{value: msg.value}(""); | ||
if (!success) revert ExecutionFailed(); | ||
|
@@ -80,9 +87,11 @@ | |
emit Reverted(destination, msg.value, data); | ||
} | ||
|
||
// Called by the TSS | ||
// Execution without ERC20 tokens, it is payable and can be used in the case of WithdrawAndCall for Gas ZRC20 | ||
// It can be also used for contract call without asset movement | ||
/// @notice Executes a call to a destination address without ERC20 tokens. | ||
/// @dev This function can only be called by the TSS address and it is payable. | ||
/// @param destination Address to call. | ||
/// @param data Calldata to pass to the call. | ||
/// @return The result of the call. | ||
function execute(address destination, bytes calldata data) external payable onlyTSS returns (bytes memory) { | ||
bytes memory result = _execute(destination, data); | ||
|
||
|
@@ -91,10 +100,13 @@ | |
return result; | ||
} | ||
|
||
// Called by the ERC20Custody contract | ||
// It call a function using ERC20 transfer | ||
// Since the goal is to allow calling contract not designed for ZetaChain specifically, it uses ERC20 allowance system | ||
// It provides allowance to destination contract and call destination contract. In the end, it remove remaining allowance and transfer remaining tokens back to the custody contract for security purposes | ||
/// @notice Executes a call to a destination contract using ERC20 tokens. | ||
/// @dev This function can only be called by the custody or connector address. | ||
/// It uses the ERC20 allowance system, resetting gateway allowance at the end. | ||
/// @param token Address of the ERC20 token. | ||
/// @param to Address of the contract to call. | ||
/// @param amount Amount of tokens to transfer. | ||
/// @param data Calldata to pass to the call. | ||
function executeWithERC20( | ||
address token, | ||
address to, | ||
|
@@ -120,8 +132,12 @@ | |
emit ExecutedWithERC20(token, to, amount, data); | ||
} | ||
|
||
// Called by the ERC20Custody contract | ||
// Directly transfers ERC20 and calls onRevert | ||
/// @notice Directly transfers ERC20 tokens and calls onRevert. | ||
/// @dev This function can only be called by the custody or connector address. | ||
/// @param token Address of the ERC20 token. | ||
/// @param to Address of the contract to call. | ||
/// @param amount Amount of tokens to transfer. | ||
/// @param data Calldata to pass to the call. | ||
function revertWithERC20( | ||
address token, | ||
address to, | ||
|
@@ -136,7 +152,8 @@ | |
emit RevertedWithERC20(token, to, amount, data); | ||
} | ||
|
||
// Deposit ETH to tss | ||
/// @notice Deposits ETH to the TSS address. | ||
/// @param receiver Address of the receiver. | ||
function deposit(address receiver) external payable { | ||
if (msg.value == 0) revert InsufficientETHAmount(); | ||
(bool deposited, ) = tssAddress.call{value: msg.value}(""); | ||
|
@@ -146,7 +163,10 @@ | |
emit Deposit(msg.sender, receiver, msg.value, address(0), ""); | ||
} | ||
|
||
// Deposit ERC20 tokens to custody/connector | ||
/// @notice Deposits ERC20 tokens to the custody or connector contract. | ||
/// @param receiver Address of the receiver. | ||
/// @param amount Amount of tokens to deposit. | ||
/// @param asset Address of the ERC20 token. | ||
function deposit(address receiver, uint256 amount, address asset) external { | ||
if (amount == 0) revert InsufficientERC20Amount(); | ||
|
||
|
@@ -155,7 +175,9 @@ | |
emit Deposit(msg.sender, receiver, amount, asset, ""); | ||
} | ||
|
||
// Deposit ETH to tss and call an omnichain smart contract | ||
/// @notice Deposits ETH to the TSS address and calls an omnichain smart contract. | ||
/// @param receiver Address of the receiver. | ||
/// @param payload Calldata to pass to the call. | ||
function depositAndCall(address receiver, bytes calldata payload) external payable { | ||
if (msg.value == 0) revert InsufficientETHAmount(); | ||
(bool deposited, ) = tssAddress.call{value: msg.value}(""); | ||
|
@@ -165,7 +187,11 @@ | |
emit Deposit(msg.sender, receiver, msg.value, address(0), payload); | ||
} | ||
|
||
// Deposit ERC20 tokens to custody/connector and call an omnichain smart contract | ||
/// @notice Deposits ERC20 tokens to the custody or connector contract and calls an omnichain smart contract. | ||
/// @param receiver Address of the receiver. | ||
/// @param amount Amount of tokens to deposit. | ||
/// @param asset Address of the ERC20 token. | ||
/// @param payload Calldata to pass to the call. | ||
function depositAndCall(address receiver, uint256 amount, address asset, bytes calldata payload) external { | ||
if (amount == 0) revert InsufficientERC20Amount(); | ||
|
||
|
@@ -174,29 +200,45 @@ | |
emit Deposit(msg.sender, receiver, amount, asset, payload); | ||
} | ||
|
||
// Call an omnichain smart contract without asset transfer | ||
/// @notice Calls an omnichain smart contract without asset transfer. | ||
/// @param receiver Address of the receiver. | ||
/// @param payload Calldata to pass to the call. | ||
function call(address receiver, bytes calldata payload) external { | ||
emit Call(msg.sender, receiver, payload); | ||
} | ||
|
||
/// @notice Sets the custody contract address. | ||
/// @param _custody Address of the custody contract. | ||
function setCustody(address _custody) external onlyTSS { | ||
if (custody != address(0)) revert CustodyInitialized(); | ||
if (_custody == address(0)) revert ZeroAddress(); | ||
|
||
custody = _custody; | ||
} | ||
|
||
function setConnector(address _zetaConnector) external onlyTSS { | ||
/// @notice Sets the connector contract address. | ||
/// @param _zetaConnector Address of the connector contract. | ||
function setConnector(address _zetaConnector) external onlyTSS { | ||
Check warning Code scanning / Slither Conformance to Solidity naming conventions Warning
Parameter GatewayEVM.setConnector(address)._zetaConnector is not in mixedCase
|
||
if (zetaConnector != address(0)) revert CustodyInitialized(); | ||
if (_zetaConnector == address(0)) revert ZeroAddress(); | ||
|
||
zetaConnector = _zetaConnector; | ||
} | ||
Check notice Code scanning / Slither Missing events access control Low |
||
|
||
/// @dev Resets the approval of a token for a specified address. | ||
/// This is used to ensure that the approval is set to zero before setting it to a new value. | ||
/// @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) { | ||
return IERC20(token).approve(to, 0); | ||
} | ||
|
||
/// @dev Transfers tokens from the sender to the asset handler. | ||
/// This function handles the transfer of tokens to either the connector or custody contract based on the asset type. | ||
/// @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 { | ||
if (token == zetaToken) { // transfer to connector | ||
// transfer amount to gateway | ||
|
@@ -210,6 +252,10 @@ | |
} | ||
} | ||
|
||
/// @dev Transfers tokens to the asset handler. | ||
/// This function handles the transfer of tokens to either the connector or custody contract based on the asset type. | ||
/// @param token Address of the ERC20 token. | ||
/// @param amount Amount of tokens to transfer. | ||
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) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: are we going to keep the "New" suffixes in the contracts? Should we omit then as this contracts move to production?