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: initialize a prototypes #162

Merged
merged 33 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
33 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
4ee9023
Merge branch 'main' into init-prototypes
skosito Jul 1, 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
2b64c79
Update contracts/prototypes/evm/GatewayEVM.sol
lumtis Jul 3, 2024
ea767f6
adding access control TODOs
lumtis Jul 3, 2024
725da8e
PR comments
skosito Jul 3, 2024
efd62ce
add more checks to withdraw function
skosito Jul 3, 2024
0ff9029
Merge branch 'main' into init-prototypes
skosito Jul 3, 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
38 changes: 38 additions & 0 deletions contracts/prototypes/ERC20CustodyNew.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

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

// As the current version, ERC20CustodyNew hold the ERC20s deposited on ZetaChain
// This version include a functionality allowing to call a contract
// ERC20Custody doesn't call smart contract directly, it passes through the Gateway contract
contract ERC20CustodyNew {
Gateway public gateway;

event Withdraw(address indexed token, address indexed to, uint256 amount);
event WithdrawAndCall(address indexed token, address indexed to, uint256 amount, bytes data);

constructor(address _gateway) {
gateway = Gateway(_gateway);
}

// Withdraw is called by TSS address, it directly transfers the tokens to the destination address without contract call
function withdraw(address token, address to, uint256 amount) external {
IERC20(token).transfer(to, amount);

emit Withdraw(token, to, amount);
}

// WithdrawAndCall is called by TSS address, it transfers the tokens and call a contract
// For this, it passes through the Gateway contract, it transfers the tokens to the Gateway contract and then calls the contract
function withdrawAndCall(address token, address to, uint256 amount, bytes calldata data) external {
skosito marked this conversation as resolved.
Show resolved Hide resolved
// Transfer the tokens to the Gateway contract
IERC20(token).transfer(address(gateway), amount);

// Forward the call to the Gateway contract
gateway.executeWithERC20(token, to, amount, data);

emit WithdrawAndCall(token, to, amount, data);
}
}
71 changes: 71 additions & 0 deletions contracts/prototypes/Gateway.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

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

// 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
contract Gateway {
error ExecutionFailed();

ERC20CustodyNew public custody;
skosito marked this conversation as resolved.
Show resolved Hide resolved

event Executed(address indexed destination, uint256 value, bytes data);
event ExecutedWithERC20(address indexed token, address indexed to, uint256 amount, bytes data);

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
// 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
function execute(address destination, bytes calldata data) external payable returns (bytes memory) {
bytes memory result = _execute(destination, data);

emit Executed(destination, msg.value, data);

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
function executeWithERC20(
address token,
address to,
uint256 amount,
bytes calldata data
lumtis marked this conversation as resolved.
Show resolved Hide resolved
) external returns (bytes memory) {
// Approve the target contract to spend the tokens
IERC20(token).approve(to, amount);

// Execute the call on the target contract
bytes memory result = _execute(to, data);
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// Reset approval
IERC20(token).approve(to, 0);

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

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

return result;
}

function setCustody(address _custody) external {
custody = ERC20CustodyNew(_custody);
}
}
34 changes: 34 additions & 0 deletions contracts/prototypes/Receiver.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

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

contract Receiver {
event ReceivedA(address sender, uint256 value, string str, uint256 num, bool flag);
event ReceivedB(address sender, string[] strs, uint256[] nums, bool flag);
event ReceivedC(address sender, uint256 amount, address token, address destination);
event ReceivedD(address sender);

// Payable function
function receiveA(string memory str, uint256 num, bool flag) external payable {
emit ReceivedA(msg.sender, msg.value, str, num, flag);
}

// Non-payable function
function receiveB(string[] memory strs, uint256[] memory nums, bool flag) external {
emit ReceivedB(msg.sender, strs, nums, flag);
}

// Function using IERC20
function receiveC(uint256 amount, address token, address destination) external {
// Transfer tokens from the Gateway contract to the destination address
IERC20(token).transferFrom(msg.sender, destination, amount);

emit ReceivedC(msg.sender, amount, token, destination);
}

// Function without parameters
function receiveD() external {
emit ReceivedD(msg.sender);
}
}
12 changes: 12 additions & 0 deletions contracts/prototypes/TestERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

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

contract TestERC20 is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}

function mint(address to, uint256 amount) external {
_mint(to, amount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# ZetaTokenConsumerZEVM
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/6aed43c93d3900874969a54408401c17997e7cb9/contracts/evm/tools/ZetaTokenConsumerZEVM.strategy.sol)

**Inherits:**
[ZetaTokenConsumer](/contracts/evm/interfaces/ZetaInterfaces.sol/interface.ZetaTokenConsumer.md), [ZetaTokenConsumerZEVMErrors](/contracts/evm/tools/ZetaTokenConsumerZEVM.strategy.sol/interface.ZetaTokenConsumerZEVMErrors.md)

*ZetaTokenConsumer for ZEVM*


## State Variables
### MAX_DEADLINE

```solidity
uint256 internal constant MAX_DEADLINE = 200;
```


### WETH9Address

```solidity
address public immutable WETH9Address;
```


### uniswapV2Router

```solidity
IUniswapV2Router02 internal immutable uniswapV2Router;
```


## Functions
### constructor


```solidity
constructor(address WETH9Address_, address uniswapV2Router_);
```

### getZetaFromEth


```solidity
function getZetaFromEth(address destinationAddress, uint256 minAmountOut) external payable override returns (uint256);
```

### getZetaFromToken


```solidity
function getZetaFromToken(
address destinationAddress,
uint256 minAmountOut,
address inputToken,
uint256 inputTokenAmount
) external override returns (uint256);
```

### getEthFromZeta


```solidity
function getEthFromZeta(address destinationAddress, uint256 minAmountOut, uint256 zetaTokenAmount)
external
override
returns (uint256);
```

### getTokenFromZeta


```solidity
function getTokenFromZeta(
address destinationAddress,
uint256 minAmountOut,
address outputToken,
uint256 zetaTokenAmount
) external override returns (uint256);
```

### hasZetaLiquidity


```solidity
function hasZetaLiquidity() external view override returns (bool);
```

### receive


```solidity
receive() external payable;
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# ZetaTokenConsumerZEVMErrors
lumtis marked this conversation as resolved.
Show resolved Hide resolved
[Git Source](https://github.com/zeta-chain/protocol-contracts/blob/6aed43c93d3900874969a54408401c17997e7cb9/contracts/evm/tools/ZetaTokenConsumerZEVM.strategy.sol)


lumtis marked this conversation as resolved.
Show resolved Hide resolved
## Errors
lumtis marked this conversation as resolved.
Show resolved Hide resolved
### InputCantBeZero
lumtis marked this conversation as resolved.
Show resolved Hide resolved

```solidity
error InputCantBeZero();
```

### ErrorSendingETH

```solidity
error ErrorSendingETH();
```

### ReentrancyError

```solidity
error ReentrancyError();
```

### NotEnoughValue

```solidity
error NotEnoughValue();
```

### InputCantBeZeta

```solidity
error InputCantBeZeta();
```

### OutputCantBeZeta

```solidity
error OutputCantBeZeta();
```

### OnlyWZETAAllowed

```solidity
error OnlyWZETAAllowed();
```

### InvalidForZEVM

```solidity
error InvalidForZEVM();
```

1 change: 1 addition & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "@nomicfoundation/hardhat-verify";
import "@typechain/hardhat";
import "tsconfig-paths/register";
import "hardhat-abi-exporter";
import "uniswap-v2-deploy-plugin";
import "./tasks/addresses";

import { getHardhatConfigNetworks } from "@zetachain/networks";
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
"ts-node": "10.8.1",
"tsconfig-paths": "^3.14.1",
"typechain": "^8.1.0",
"typescript": "^4.6.3"
"typescript": "^4.6.3",
"uniswap-v2-deploy-plugin": "^0.0.4"
},
"files": [
"contracts",
Expand All @@ -78,6 +79,7 @@
"lint:fix": "npx eslint . --ext .js,.ts,.json --fix",
"prepublishOnly": "yarn build",
"test": "yarn compile && npx hardhat test",
"test:prototypes": "yarn compile && npx hardhat test test/prototypes/*",
"tsc:watch": "npx tsc --watch"
},
"types": "./dist/lib/index.d.ts",
Expand Down
Loading
Loading