Skip to content

Commit

Permalink
Merge pull request #107 from poanetwork/develop
Browse files Browse the repository at this point in the history
Merging the develop branch containing the ERC-TO-NATIVE mode to the master branch
  • Loading branch information
akolotov authored Nov 6, 2018
2 parents 64dfc32 + d2d6903 commit 1f61c69
Show file tree
Hide file tree
Showing 55 changed files with 6,918 additions and 2,535 deletions.
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
deploy/node_modules
.git
.dockerignore
deploy/.env
docker-compose.yml
Dockerfile
*.log
flats
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM node:8

WORKDIR /contracts

COPY package.json .
COPY package-lock.json .
RUN npm install

COPY ./deploy/package.json ./deploy/
COPY ./deploy/package-lock.json ./deploy/
RUN cd ./deploy; npm install; cd ..

COPY . .
RUN npm run compile
RUN bash flatten.sh

ENV PATH="/contracts/:${PATH}"
174 changes: 174 additions & 0 deletions GAS_CONSUMPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
## Gas Consumption

### `NATIVE-TO-ERC` Bridge Mode

#### Deployment
##### Home
Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
EternalStorageProxy|deployment|378510|378510|378510
BridgeValidators|deployment|1144207|1144207|1144207
EternalStorageProxy|upgradeTo|35871|30924|30913
BridgeValidators|initialize|187738|280847|253949
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
EternalStorageProxy|deployment|378510|378510|378510
HomeBridgeNativeToErc|deployment|3327263|3327263|3327263
EternalStorageProxy|upgradeTo|35871|30924|30913
HomeBridgeNativeToErc|initialize|190051|190947|190755
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
Total| |5739327|5823438|5796326

##### Foreign
Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
ERC677BridgeToken|deployment|1498202|1499226|1498829
EternalStorageProxy|deployment|378510|378510|378510
BridgeValidators|deployment|1144207|1144207|1144207
EternalStorageProxy|upgradeTo|35871|30924|30913
BridgeValidators|initialize|187738|280847|253949
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
EternalStorageProxy|deployment|378510|378510|378510
ForeignBridgeNativeToErc|deployment|2768705|2768705|2768705
EternalStorageProxy|upgradeTo|35871|30924|30913
ForeignBridgeNativeToErc|initialize|213493|213557|213549
ERC677BridgeToken|setBridgeContract|29432|44432|39432
ERC677BridgeToken|transferOwnership|30860|30924|30913
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
Total| |6762705|6862072|6829736

#### Usage

##### Validators

Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
To sign at the Home (each validator)|
HomeBridgeNativeToErc|submitSignature|159362|275135|220127
To relay signatures from the Home to the Foreign (one validator)|
ForeignBridgeNativeToErc|executeSignatures|89201|146127|120917
To sign and relay from the Foreign to the Home (each validator)|
HomeBridgeNativeToErc|executeAffirmation|64314|107669|83596

##### Users

Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
To request transfer from the Home to the Foreign|
HomeBridgeNativeToErc|fallback|46982|46982|46982
To request transfer from the Foreign to the Home|
ERC677BridgeToken|transferAndCall|58370|166206|92399


### `ERC-TO-ERC` Bridge Mode

#### Deployment
##### Home
Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
EternalStorageProxy|deployment|378510|378510|378510
BridgeValidators|deployment|1144207|1144207|1144207
EternalStorageProxy|upgradeTo|35871|30924|30913
BridgeValidators|initialize|187738|280847|253949
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
EternalStorageProxy|deployment|378510|378510|378510
HomeBridgeErcToErc|deployment|3528509|3528509|3528509
EternalStorageProxy|upgradeTo|35871|30924|30913
ERC677BridgeToken|deployment|1498202|1499226|1498829
ERC677BridgeToken|setBridgeContract|29432|44432|39432
ERC677BridgeToken|transferOwnership|30860|30924|30913
HomeBridgeErcToErc|initialize|212299|213195|213003
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
Total| |7521315|7621514|7588994

##### Foreign
Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
EternalStorageProxy|deployment|378510|378510|378510
BridgeValidators|deployment|1144207|1144207|1144207
EternalStorageProxy|upgradeTo|35871|30924|30913
BridgeValidators|initialize|187738|280847|253949
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
EternalStorageProxy|deployment|378510|378510|378510
ForeignBridgeErcToErc|deployment|2449436|2449436|2449436
EternalStorageProxy|upgradeTo|35871|30924|30913
ForeignBridgeErcToErc|initialize|150614|150614|150614
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
Total| |4822063|4905278|4878358

#### Usage

##### Validators

Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
To sign at the Home (each validator)|
HomeBridgeErcToErc|submitSignature|159386|275159|220171
To relay signatures from the Home to the Foreign (one validator)|
ForeignBridgeErcToErc|executeSignatures|73779|115769|93027
To sign and relay from the Foreign to the Home (each validator)|
HomeBridgeErcToErc|executeAffirmation|79336|134607|108215

##### Users

Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
To request transfer from the Home to the Foreign|
ERC677BridgeToken|transferAndCall|58370|166206|92399
To request transfer from the Foreign to the Home|
ERC677BridgeToken|transfer|37691|86589|55000


### `ERC-TO-NATIVE` Bridge Mode

#### Deployment
##### Home
Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
EternalStorageProxy|deployment|378510|378510|378510
BridgeValidators|deployment|1144207|1144207|1144207
EternalStorageProxy|upgradeTo|35871|30924|30913
BridgeValidators|initialize|187738|280847|253949
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
EternalStorageProxy|deployment|378510|378510|378510
HomeBridgeErcToNative|deployment|3757420|3757420|3757420
EternalStorageProxy|upgradeTo|35871|30924|30913
HomeBridgeErcToNative|initialize|196910|213930|210795
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
Total| |6176343|6276578|6246523

##### Foreign
Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
EternalStorageProxy|deployment|378510|378510|378510
BridgeValidators|deployment|1144207|1144207|1144207
EternalStorageProxy|upgradeTo|35871|30924|30913
BridgeValidators|initialize|187738|280847|253949
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
EternalStorageProxy|deployment|378510|378510|378510
ForeignBridgeErcToNative|deployment|2449564|2449564|2449564
EternalStorageProxy|upgradeTo|35871|30924|30913
ForeignBridgeErcToNative|initialize|150614|150614|150614
EternalStorageProxy|transferProxyOwnership|30653|30653|30653
Total| |

#### Usage

##### Validators

Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
To sign at the Home (each validator)|
HomeBridgeErcToNative|submitSignature|159428|275201|220206
To relay signatures from the Home to the Foreign (one validator)|
ForeignBridgeErcToNative|executeSignatures|73779|115769|92985
To sign and relay from the Foreign to the Home (each validator)|
HomeBridgeErcToNative|executeAffirmation|64380|140744|97562

##### Users

Contract | Method | Min | Max | Avg
---- | ---- | ---- | ---- | ----
To request transfer from the Home to the Foreign|
HomeBridgeErcToNative|fallback|80174|80174|80174
To request transfer from the Foreign to the Home|
ERC677BridgeToken|transfer|37691|86589|55000
75 changes: 70 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ The POA Bridge allows users to transfer assets between two chains in the Ethereu
Currently, the contracts support two types of relay operations:
* Tokenize the native coin in one blockchain network (Home) into an ERC20 token in another network (Foreign).
* Swap a token presented by an existing ERC20 contract in a Foreign network into an ERC20 token in the Home network, where one pair of bridge contracts corresponds to one pair of ERC20 tokens.
* to mint new native coins in Home blockchain network from a token presented by an existing ERC20 contract in a Foreign network.


### Components
Expand All @@ -35,6 +36,7 @@ The POA bridge contracts consist of several components:
* Depending on the type of relay operations the following components are also used:
* in `NATIVE-TO-ERC` mode: the ERC20 token (in fact, the ERC677 extension is used) is deployed on the Foreign network;
* in `ERC-TO-ERC` mode: the ERC20 token (in fact, the ERC677 extension is used) is deployed on the Home network;
* in `ERC-TO-NATIVE` mode: The home network nodes must support consensus engine that allows using a smart contract for block reward calculation;
* The **Validators** smart contract is deployed in both the POA.Network and the Ethereum Mainnet.

### Bridge Roles and Responsibilities
Expand All @@ -55,26 +57,89 @@ Responsibilities and roles of the bridge:
- **User** role:
- sends assets to Bridge contracts:
- in `NATIVE-TO-ERC` mode: send native coins to the Home Bridge to receive ERC20 tokens from the Foreign Bridge, send ERC20 tokens to the Foreign Bridge to unlock native coins from the Home Bridge;
- in `ERC-TO-ERC` mode: transfer ERC20 tokens to the Foreign Bridge to mint ERC20 tokens on the Home Network, transfer ERC20 tokens to the Home Bridge to unlock ERC20 tokens on Foreign networks.
- in `ERC-TO-ERC` mode: transfer ERC20 tokens to the Foreign Bridge to mint ERC20 tokens on the Home Network, transfer ERC20 tokens to the Home Bridge to unlock ERC20 tokens on Foreign networks;
- in `ERC-TO-NATIVE` mode: send ERC20 tokens to the Foreign Bridge to receive native coins from the Home Bridge, send native coins to the Home Bridge to unlock ERC20 tokens from the Foreign Bridge.

## Usage

### Install Dependencies
There are two ways to deploy contracts:
* install and use NodeJS
* use Docker to deploy

### Deployment with NodeJS

#### Install Dependencies
```bash
npm install
```
### Deploy
#### Deploy
Please the [README.md](deploy/README.md) in the `deploy` folder for instructions and .env file configuration

### Test
#### Test
```bash
npm test
```

### Flatten
#### Flatten
Fattened contracts can be used to verify the contract code in a block explorer like BlockScout or Etherscan.
The following command will prepare flattened version of the contracts:

```bash
npm run flatten
```
The flattened contracts can be found in the `flats` directory.

### Deployment in the Docker environment
[Docker](https://www.docker.com/community-edition) and [Docker Compose](https://docs.docker.com/compose/install/) can be used to deploy contracts without NodeJS installed on the system.
If you are on Linux, we recommend you [create a docker group and add your user to it](https://docs.docker.com/install/linux/linux-postinstall/), so that you can use the CLI without `sudo`.

#### Prepare the docker container
```bash
docker-compose up --build
```
_Note: The container must be rebuilt every time the code in a contract or deployment script is changed._

#### Deploy the contracts
1. Create the `.env` file in the `deploy` directory as described in the deployment [README.md](deploy/README.md).
2. Run deployment process:
```bash
docker-compose run bridge-contracts deploy.sh
```
or with Linux:
```bash
./deploy.sh
```

#### Copy flatten sources (if needed)
1. Discover the container name:
```bash
docker-compose images bridge-contracts
```
2. In the following command, use the container name to copy the flattened contracts code to the current working directory. The contracts will be located in the `flats` directory.
```bash
docker cp name-of-your-container:/contracts/flats ./
```

#### Shutdown the container
If the container is no longer needed, it can be shutdown:
```bash
docker-compose down
```

### Gas Consumption
The [GAS_CONSUMPTION](GAS_CONSUMPTION.md) file includes Min, Max, and Avg gas consumption figures for contracts associated with each bridge mode.

### Testing environment
To test the bridge scripts in ERC20-to-ERC20 mode on a testnet like Sokol or Kovan, you must deploy an ERC20 token to the foreign network.
This can be done by running the following command:
```bash
cd deploy
node testenv-deploy.js token
```
or with Docker:
```bash
./deploy.sh token
```

## Contributing

Expand Down
22 changes: 18 additions & 4 deletions contracts/ERC677BridgeToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import "openzeppelin-solidity/contracts/token/ERC20/MintableToken.sol";
import "openzeppelin-solidity/contracts/token/ERC20/DetailedERC20.sol";
import "./IBurnableMintableERC677Token.sol";
import "./ERC677Receiver.sol";
import "./libraries/Version.sol";


contract ERC677BridgeToken is
Expand All @@ -14,14 +13,21 @@ contract ERC677BridgeToken is
BurnableToken,
MintableToken {

Version.Version public getTokenInterfacesVersion = Version.Version(2, 0, 0);
address public bridgeContract;

event ContractFallbackCallFailed(address from, address to, uint value);

constructor(
string _name,
string _symbol,
uint8 _decimals)
public DetailedERC20(_name, _symbol, _decimals) {}

function setBridgeContract(address _bridgeContract) onlyOwner public {
require(_bridgeContract != address(0) && isContract(_bridgeContract));
bridgeContract = _bridgeContract;
}

modifier validRecipient(address _recipient) {
require(_recipient != address(0) && _recipient != address(this));
_;
Expand All @@ -39,6 +45,10 @@ contract ERC677BridgeToken is
return true;
}

function getTokenInterfacesVersion() public pure returns(uint64 major, uint64 minor, uint64 patch) {
return (2, 0, 0);
}

function superTransfer(address _to, uint256 _value) internal returns(bool)
{
return super.transfer(_to, _value);
Expand All @@ -47,8 +57,12 @@ contract ERC677BridgeToken is
function transfer(address _to, uint256 _value) public returns (bool)
{
require(superTransfer(_to, _value));
if (isContract(_to)) {
contractFallback(_to, _value, new bytes(0));
if (isContract(_to) && !contractFallback(_to, _value, new bytes(0))) {
if (_to == bridgeContract) {
revert();
} else {
emit ContractFallbackCallFailed(msg.sender, _to, _value);
}
}
return true;
}
Expand Down
9 changes: 9 additions & 0 deletions contracts/IBlockReward.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pragma solidity 0.4.24;


interface IBlockReward {
function addExtraReceiver(uint256 _amount, address _receiver) external;
function mintedTotally() public view returns (uint256);
function mintedTotallyByBridge(address _bridge) public view returns(uint256);
function bridgesAllowedLength() external view returns(uint256);
}
12 changes: 0 additions & 12 deletions contracts/libraries/Version.sol

This file was deleted.

Loading

0 comments on commit 1f61c69

Please sign in to comment.