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

Merge the develop branch to the master branch, preparation to v2.0.0-rc5 #45

Merged
merged 5 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ flats
contracts.sublime-project
contracts.sublime-workspace
build/
package-lock.json
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
build
coverage
deploy/src/remix-helpers
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
- name: Prepare tag names
id: prep
run: |
DOCKER_IMAGE=poanetwork/nft-omnibridge-contracts
DOCKER_IMAGE=omnibridge/nft-contracts
if [[ $GITHUB_REF == refs/tags/* ]]; then
echo ::set-output name=tags::${DOCKER_IMAGE}:${GITHUB_REF#refs/tags/},${DOCKER_IMAGE}:latest
else
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ deploy/*.env*
!deploy/.env.example
deploy/bridgeDeploymentResults.json
coverage.json
package-lock.json
19 changes: 15 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM node:14 as contracts

WORKDIR /contracts
WORKDIR /workdir

COPY package.json yarn.lock ./
RUN yarn
Expand All @@ -11,14 +11,25 @@ RUN yarn compile

FROM node:14

WORKDIR /contracts
WORKDIR /workdir

COPY package.json yarn.lock ./
RUN yarn install --prod

COPY --from=contracts /contracts/build ./build
# Allows remixd to be run within a docker container
RUN sed -i s/127.0.0.1/0.0.0.0/g node_modules/@remix-project/remixd/websocket.js

COPY truffle-config.js truffle-config.js
# No need to have coverage module within the container
RUN sed -i s/\'solidity-coverage\'\,\ // truffle-config.js

COPY ./contracts ./contracts

COPY --from=contracts /workdir/build ./build

COPY deploy.sh deploy.sh
COPY ./deploy ./deploy

ENV PATH="/contracts/:${PATH}"
EXPOSE 65520

ENV PATH="/workdir:/workdir/node_modules/.bin:${PATH}"
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
[![Join the chat at https://gitter.im/poanetwork/poa-bridge](https://badges.gitter.im/poanetwork/poa-bridge.svg)](https://gitter.im/poanetwork/poa-bridge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://github.com/poanetwork/omnibridge-nft/workflows/omnibridge-nft-contracts/badge.svg?branch=master)](https://github.com/poanetwork/omnibridge-nft/workflows/omnibridge-nft-contracts/badge.svg?branch=master)
[![Build Status](https://github.com/omni/omnibridge-nft/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/omni/omnibridge-nft/actions/workflows/main.yml)

# Omnibridge NFT Smart Contracts
These contracts provide the core functionality for the Omnibridge NFT AMB extension.
NFT OmniBridge Contracts
====

These contracts provide the core functionality for the NFT Omnibridge AMB extension.

More details about AMB (Arbitrary Message Bridge) extensions can be found [here](https://docs.tokenbridge.net/amb-bridge/about-amb-bridge). The AMB repository is [poanetwork/tokenbridge-contracts](https://github.com/poanetwork/tokenbridge-contracts).

## License

Expand Down
42 changes: 42 additions & 0 deletions REMIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
How to access the contracts in the Remix IDE
====

It is possible to use the docker container to modify, test and deploy the contracts in the Remix IDE.

## Read-Only Access

If it is not needed to modify the contracts, they can be opened in the Remix IDE without necessity to clone the repo:

1. Pull the docker image
```
docker pull omnibridge/nft-contracts:latest
```

2. Run the container
```
docker run -d --rm --name nft-ob-remixd -p 65520:65520
omnibridge/nft-contracts:latest yarn remixd
```

3. Open a new workspace [through connectivity to localhost](https://remix-ide.readthedocs.io/en/latest/remixd.html) in the Remix IDE. It is important to use HTTPS to access the IDE: https://remix.ethereum.org/.

## Keep the changes

In case of the modification of the contracts it makes sense to mount the local directory with the git repo in the Remix IDE.

1. Pull the docker image
```
docker pull omnibridge/nft-contracts:latest
```
2. Move to the directory with the contracts.
```
cd omnibridge-nft
```

3. Run the container
```
docker run -d --rm --name nft-ob-remixd -p 65520:65520
-v $(pwd):/workdir omnibridge/nft-contracts:latest yarn remixd
```

4. Open a new workspace [through connectivity to localhost](https://remix-ide.readthedocs.io/en/latest/remixd.html) in the Remix IDE. It is important to use HTTPS to access the IDE: https://remix.ethereum.org/.
35 changes: 35 additions & 0 deletions contracts/mocks/NFTWithoutMetadata.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
pragma solidity 0.7.5;

import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "../interfaces/IERC1155TokenReceiver.sol";

contract NFTWithoutMetadata {
function safeTransferFrom(
address _from,
address _to,
uint256 _id,
bytes memory _data
) external {
IERC721Receiver to = IERC721Receiver(_to);
require(to.onERC721Received(msg.sender, _from, _id, _data) == to.onERC721Received.selector);
}

function safeTransferFrom(
address _from,
address _to,
uint256 _id,
uint256 _amount,
bytes memory _data
) external {
IERC1155TokenReceiver to = IERC1155TokenReceiver(_to);
require(to.onERC1155Received(msg.sender, _from, _id, _amount, _data) == to.onERC1155Received.selector);
}

function balanceOf(address, uint256) external view returns (uint256) {
return 1000;
}

function ownerOf(uint256) external view returns (address) {
return msg.sender;
}
}
14 changes: 13 additions & 1 deletion contracts/tokens/ERC1155BridgeToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ contract ERC1155BridgeToken is ERC1155, IBurnableMintableERC1155Token {
_burnBatch(msg.sender, _tokenIds, _values);
}

/**
* @dev Updated bridged token name/symbol parameters.
* Only bridge owner or bridge itself can call this method.
* @param _name new name parameter, will be saved as is, without additional suffixes like " from Mainnet".
* @param _symbol new symbol parameter.
*/
function setMetadata(string calldata _name, string calldata _symbol) external onlyOwner {
require(bytes(_name).length > 0 && bytes(_symbol).length > 0);
name = _name;
symbol = _symbol;
}

/**
* @dev Updates the bridge contract address.
* Can be called by bridge owner after token contract was instantiated.
Expand Down Expand Up @@ -170,6 +182,6 @@ contract ERC1155BridgeToken is ERC1155, IBurnableMintableERC1155Token {
uint64 patch
)
{
return (1, 1, 0);
return (1, 2, 0);
}
}
25 changes: 24 additions & 1 deletion contracts/tokens/ERC721BridgeToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,29 @@ contract ERC721BridgeToken is ERC721, IBurnableMintableERC721Token {
_burn(_tokenId);
}

// hack to access private fields in ERC721 contract
struct MetadataStorage {
string name;
string symbol;
}

/**
* @dev Updated bridged token name/symbol parameters.
* Only bridge owner or bridge itself can call this method.
* @param _name new name parameter, will be saved as is, without additional suffixes like " from Mainnet".
* @param _symbol new symbol parameter.
*/
function setMetadata(string calldata _name, string calldata _symbol) external onlyOwner {
require(bytes(_name).length > 0 && bytes(_symbol).length > 0);

MetadataStorage storage metadata;
assembly {
metadata.slot := 6
}
metadata.name = _name;
metadata.symbol = _symbol;
}

/**
* @dev Sets the base URI for all tokens.
* Can be called by bridge owner after token contract was instantiated.
Expand Down Expand Up @@ -118,6 +141,6 @@ contract ERC721BridgeToken is ERC721, IBurnableMintableERC721Token {
uint64 patch
)
{
return (1, 0, 1);
return (1, 1, 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,18 @@ abstract contract BasicNFTOmnibridge is
address bridgedToken = bridgedTokenAddress(_token);
if (bridgedToken == address(0)) {
if (bytes(_name).length == 0) {
require(bytes(_symbol).length > 0);
_name = _symbol;
} else if (bytes(_symbol).length == 0) {
_symbol = _name;
if (bytes(_symbol).length > 0) {
_name = _transformName(_symbol);
}
} else {
if (bytes(_symbol).length == 0) {
_symbol = _name;
}
_name = _transformName(_name);
}
bridgedToken = _values.length > 0
? address(new ERC1155TokenProxy(tokenImageERC1155(), _transformName(_name), _symbol, address(this)))
: address(new ERC721TokenProxy(tokenImageERC721(), _transformName(_name), _symbol, address(this)));
? address(new ERC1155TokenProxy(tokenImageERC1155(), _name, _symbol, address(this)))
: address(new ERC721TokenProxy(tokenImageERC721(), _name, _symbol, address(this)));
_setTokenAddressPair(_token, bridgedToken);
}

Expand Down Expand Up @@ -296,8 +300,6 @@ abstract contract BasicNFTOmnibridge is
string memory name = _readName(_token);
string memory symbol = _readSymbol(_token);

require(bytes(name).length > 0 || bytes(symbol).length > 0);

return
abi.encodeWithSelector(
this.deployAndHandleBridgedNFT.selector,
Expand Down
20 changes: 2 additions & 18 deletions deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,5 @@ if [ -f /.dockerenv ]; then
exit 0
fi

which docker-compose > /dev/null
if [ "$?" == "1" ]; then
echo "docker-compose is needed to use this type of deployment"
exit 1
fi

if [ ! -f ./deploy/.env ]; then
echo "The .env file not found in the 'deploy' directory"
exit 3
fi

docker-compose images nft-omnibridge-contracts >/dev/null 2>/dev/null
if [ "$?" == "1" ]; then
echo "Docker image 'nft-omnibridge-contracts' not found"
exit 2
fi

docker-compose run nft-omnibridge-contracts deploy.sh "$@"
echo "The deployment must start withing the docker container"
exit 1
8 changes: 0 additions & 8 deletions deploy/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@ FOREIGN_AMB_BRIDGE=
HOME_MEDIATOR_REQUEST_GAS_LIMIT=
FOREIGN_MEDIATOR_REQUEST_GAS_LIMIT=

# Supported explorers: Blockscout, etherscan
HOME_EXPLORER_URL=https://blockscout.com/poa/sokol/api
HOME_EXPLORER_API_KEY=

# Supported explorers: Blockscout, etherscan
FOREIGN_EXPLORER_URL=https://api-kovan.etherscan.io/api
FOREIGN_EXPLORER_API_KEY=

HOME_ERC721_TOKEN_IMAGE=0x
HOME_ERC1155_TOKEN_IMAGE=0x
HOME_FORWARDING_RULES_MANAGER=false
Expand Down
73 changes: 47 additions & 26 deletions deploy/README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,63 @@
# How to Deploy POA Bridge Contracts
How to deploy NFT OmniBridge AMB extension contracts
====

In order to deploy bridge contracts you must run `yarn` to install all dependencies. For more information, see the [project README](../README.md).
There are two options to deploy NFT OB contracts:
* with docker image, it could be useful for systems where there is no Node.JS environment configured
* with `yarn`, for the cases where customization in the contracts code is required

If necessary, deploy and configure a multi-sig wallet contract to manage the bridge contracts after deployment. We have not audited any wallets for security, but have used [Gnosis Safe](https://gnosis-safe.io/) with success.

## Deployment with Docker

It is assumed that Docker is installed on the system.

1. Pull the docker image:

```
docker pull omnibridge/nft-contracts:latest
```

2. Create a `nft-ob.env` file with the NFT OB configuration parameters. See below for comments related to each parameter.

3. Add funds to the deployment account in both the Home and Foreign networks.

4. Run the docker container:
```
docker run -ti --rm --env-file nft-ob.env omnibridge/nft-contracts:latest deploy.sh
```

## Deployment with Yarn

Before deploying of the NFT OB contracts you must run `yarn` to install all dependencies.

1. Compile the source contracts.
```
cd ..
yarn compile
```
```
cd ..
yarn compile
```

2. Create a `.env` file.
```
cd deploy
cp env.example .env
```
```
cd deploy
cp env.example .env
```

3. If necessary, deploy and configure a multi-sig wallet contract to manage the bridge contracts after deployment. We have not audited any wallets for security, but have used https://github.com/gnosis/MultiSigWallet/ with success.
3. Adjust the parameters in the `.env` file. See below for comments related to each parameter.

4. Adjust the parameters in the `.env` file depending on the desired bridge mode. See below for comments related to each parameter.
4. Add funds to the deployment account in both the Home and Foreign networks.

5. Add funds to the deployment accounts in both the Home and Foreign networks.
5. Run `yarn deploy`.

6. Run `yarn deploy`.
## Contracts verification

## `OMNIBRIDGE_NFT` Bridge Mode Configuration Example.
The contracts are not automatically verified during deployment. In order to publish the contracts' code in Etherscan/Blockscout, follow [these instructions](VERIFICATION.md)

This example of an `.env` file for the `OMNIBRIDGE_NFT` bridge mode includes comments describing each parameter.
## NFT OB configuration parameters clarification

This example of an `.env` file for the NFT OmniBridge includes comments describing each parameter.

```bash
# The type of bridge. Defines set of contracts to be deployed.
# Don't change this parameter
BRIDGE_MODE=OMNIBRIDGE_NFT

# The private key hex value of the account responsible for contracts
Expand Down Expand Up @@ -102,13 +132,4 @@ HOME_TOKEN_NAME_SUFFIX=""
# suffix used for token names for tokens bridged from Home to Foreign
# usually you might want it to start with a space character
FOREIGN_TOKEN_NAME_SUFFIX=""

# The api url of an explorer to verify all the deployed contracts in Home network. Supported explorers: Blockscout, etherscan
#HOME_EXPLORER_URL=https://blockscout.com/poa/core/api
# The api key of the explorer api, if required, used to verify all the deployed contracts in Home network.
#HOME_EXPLORER_API_KEY=
# The api url of an explorer to verify all the deployed contracts in Foreign network. Supported explorers: Blockscout, etherscan
#FOREIGN_EXPLORER_URL=https://api.etherscan.io/api
# The api key of the explorer api, if required, used to verify all the deployed contracts in Foreign network.
#FOREIGN_EXPLORER_API_KEY=
```
Loading