"` for the url of your node for that network and the json rpc port. `Remember to do it for both networks`.
-Also you need to create a `federetaros.key` file with the federator private in it.
-Once you have changed this configurations create the docker image using.
-`docker build . -t fed-tokenbridge`
-
-Then run `docker run --rm -v $PWD/federator/config:/app/federator/config --name=fed-tokenbridge fed-tokenbridge:latest` to start the image.
+There is a federation in charge of notifying the events that happend in the bridge of one chain to the other. The federation is composed by oracles listening the events created in one chain and sending it to the other chain. When the majority of the federators voted an event, the bridge accepts the event as valid and releases the tokens on the other side.
+See the ['federator'](./federator/README.md) for more information about the federator.
\ No newline at end of file
diff --git a/docs/DappGuide.md b/docs/DappGuide.md
index fc2146250..072578966 100644
--- a/docs/DappGuide.md
+++ b/docs/DappGuide.md
@@ -3,7 +3,7 @@
### Description
This guide describes the steps to transfer tokens using the Web Interface for the RSK Tokenbridge system. Please refer to the project documentation if you’d like to know more about how this bridge works.
-It is possible to test the transfer of tokens between RSK and Kovan networks using the RSK Tokenbridge web interface. This will require access to a Chrome or Chromium web browser and install one of the following wallets [Metamask with custom network](https://github.com/rsksmart/rskj/wiki/Configure-Metamask-to-connect-with-RSK) or [Nifty Wallet](https://chrome.google.com/webstore/detail/nifty-wallet/jbdaocneiiinmjbjlgalhcelgbejmnid). There has been a breaking change in Nifty wallet since version 5.0.0 if you created you account before that time you can just use the RSK Testnet option out of the box, if you created the account after that version you will need to [use a custom network](https://developers.rsk.co/tutorials/resolve-nifty-issue/#add-rsk-as-custom-node) to keep the same address in RSK and Ethereum.
+It is possible to test the transfer of tokens between RSK and Kovan networks using the RSK Tokenbridge web interface. This will require access to a Chrome or Chromium web browser and install one of the following wallets [Metamask with custom network](https://developers.rsk.co/develop/apps/wallets/metamask/) or [Nifty Wallet](https://chrome.google.com/webstore/detail/nifty-wallet/jbdaocneiiinmjbjlgalhcelgbejmnid). The derivation path used in RSK is different from the one used in Ethereum, so you need to [use a custom network](https://developers.rsk.co/tutorials/resolve-nifty-issue/#add-rsk-as-custom-node) to keep the same address in RSK and Ethereum.
## Steps
Go to the Dapp [https://tokenbridge.rsk.co/](https://tokenbridge.rsk.co/) for mainnet or [https://testnet.tokenbridge.rsk.co/](https://testnet.tokenbridge.rsk.co/) for testnet.
@@ -13,13 +13,13 @@ First **log in** with your wallet (metamask or nifty) and select the network of
-If everything is correct, you will see the following:
+If everything is correct, you will see the following screen:
-Then **select the token** that you want to transfer. For example select the tRIF token (you can obtain them from the [Rif Faucet](https://faucet.rifos.org/)).
+Then **select the token** that you want to transfer. For example, tRIF token (you can obtain them from the [Rif Faucet](https://faucet.rifos.org/)).
@@ -31,21 +31,21 @@ Once you have selected it, enter the amount you want to transfer, then click **C
-When the process starts you will see a **list of the steps needed** to cross the tokens.
+As soon as the process starts, you will see a **list of the steps needed** to cross the tokens.
-The second and third steps will show a message pop-up to confirm the transaction, **submit the transaction**. The following image gives an example of the confirmation popup. This **steps require around 30 seconds each** for the transaction to be mined.
+The second and third step will show a message pop-up to confirm the transaction, **submit the transaction**. The following image gives an example of the confirmation popup. This **steps require around 30 seconds each** for the transaction to be mined.
-Once all the steps are done, you have to **wait around 5 minutes in testnet or 1 hour in mainnet** for the tokens to cross. You can **check the token contract on the other network** by clicking on the symbol (red arrow on the image).
-You can also change the network on you wallet (in this case we would change to Kovan). To do this add the token to your wallet using the address of the crossed token contract (red arrow on the image) in your wallet.
+Once all the steps are done, you have to **wait around 5 minutes in testnet or 1 hour in mainnet** for the tokens to cross. You can **check the token contract on the other network** by clicking on the symbol (red arrow on the image).
+You can also change the network on you wallet (in this case we would change to Kovan). To do this, add the token to your wallet using the address of the crossed token contract (red arrow on the image) in your wallet.
@@ -54,4 +54,4 @@ You can also change the network on you wallet (in this case we would change to K
This address can be used to verify the balance and confirm that the tokens were effectively transferred to the other network.
-If you want to **cross back the tokens is the same process** but you'll need to select the other network in your wallet, in this case it's the Kovan network.
\ No newline at end of file
+If you want to **cross back the tokens is the same process** but you'll need to select the other network in your wallet, in this case it's the Kovan network.
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 3ff616608..955db8b72 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -1,53 +1,76 @@
# Token Bridge FAQ
## What is the Token Bridge?
-The Token Bridge is an interoperability protocol which allows users to move their own RSK or Ethereum Tokens between networks in a quick and cost-efficient manner.
-The UI is available at [https://tokenbridge.rsk.co/](https://tokenbridge.rsk.co/) or for testnet [https://testnet.tokenbridge.rsk.co/](https://testnet.tokenbridge.rsk.co/)
-## What is a Side Token?
-Side Token is an ERC777 representation of a ERC20 tokens which is on the other network(could be on Ethereum or RSK network). The Side Token displays the exact same properties as the standard ERC20 token and allows it to be used in all the same places that offer ERC20 compatibility.
+The Token Bridge is an interoperability protocol which allows users to move their own RSK or Ethereum ERC20 Tokens between networks in a quick and cost-efficient manner.
+The UI is available at:
+
+- Mainnet: [tokenbridge.rsk.co](https://tokenbridge.rsk.co/)
+- Testnet: [testnet.tokenbridge.rsk.co](https://testnet.tokenbridge.rsk.co/)
+
+
+
+
+
+## What is a Side Token (mirror ERC20)?
+
+Side Token is an ERC777 representation of a ERC20 compatible tokens which is on the other network(could be on Ethereum or RSK network). The Side Token displays the exact same properties as the standard ERC20 token and allows it to be used in all the same places as ERC20.
## What is the purpose of having a Side Token?
-Side Tokens are minted to prove cross chain bridges can work in a safe and secure manner with 2 standalone blockchains. We believe this kind of interoperability technology offers a lot of possibilities for smart contract owners, as they may prefer to do certain operations in one chain and anothers in other one. By connecting blockchains with these bridges you allow for a variety of new use cases that never existed before.
+
+Side Tokens are minted to prove cross chain bridges can work in a safe and secure manner with 2 standalone blockchains. We believe this kind of interoperability technology offers a lot of possibilities for smart contract owners, as they may prefer to do certain operations in one chain, and others in another one. By connecting blockchains with these bridges you allow for a variety of new use cases that never existed before.
## Will the supply of the original token will increase as a result of Side Tokens?
+
No! It’s important to note that there will be no increase in the original tokens. The existing amount of circulating original tokens will stay the same and simply be distributed across 2 networks (RSK Network & Ethereum network) instead of 1.
## What is the difference between original tokens and Side Tokens?
-The original token native tokens lives on the network that it was deployed for example Ethereum, while the Side Token is a representation of the original token on the other network, in this example Ethereum.
+
+The original token lives on the network that it was deployed for example Ethereum, while the Side Token is a representation of the original token on the other network, for example RSK.
## What is the Side Token Contract Address, Symbol, and # of Decimal Places in order to add it as a Custom Coin on MyEtherWallet?
-The symbol of the SideToken is the original token symbol with an r prefix if it is created in RSK or an e prefix if it is created in Ethereum. For example, if we cross the RIF token to Ethereum, the Side Token symbol would be eRIF.
-The number of Decimal places will be 18. This are the ['addresses'](./docs/ContractAdddresses.md) of the deployed contrats in the different networks.
+The symbol of the Side Token is the original token symbol with an `r` prefix if it is created in RSK or an `e` prefix if it is created in Ethereum. For example, if we cross the `RIF` token from RSK to Ethereum, the Side Token symbol would be `eRIF`.
+The number of Decimal places will be 18. This are the ['addresses'](./docs/ContractAdddresses.md) of the deployed contrats in the different networks.
## How do I transform my original tokens to Side Tokens?
-The Token Bridge will be a public DApp where users will be able to access by using Nifty Wallet or Metamask. You will be able to send your original tokens and receive an equivalent amount of Side Tokens on the other network. By toggling the network on Nifty or Metamask, you’re also able to transfer the other way around and send Side Tokens tokens to the original token.
+
+The Token Bridge will be a public DApp where users will be able to access by using Nifty Wallet or Metamask. You will be able to send your original tokens and receive an equivalent amount of Side Tokens on the other network. By toggling the network on Nifty or Metamask, you’re also able to transfer the other way around, by sending Side Tokens and receive original tokens.
## If I sell my Side Tokens, what happens to my original tokens?
-Upon receiving your you no longer own your original tokens. The moment you use the bridge to send them to the other network (RSK or Ethereum), they are locked up and stored in the contract address. Thus you effectively have no original tokens on the original Network and now have Side Tokens on the other network.
+
+Upon receiving your Side Tokens, you no longer own your original tokens. The moment you use the bridge to send them to the other network (RSK or Ethereum), they are locked up and stored in the contract address. Thus you effectively have no original tokens on the original network and now have Side Tokens on the other network.
## Is there a limit on how many tokens can be bridged over?
-There is no limit, however, there is a daily quota. Hypothetically the entire circulating supply can be bridged, though this likely will never happen since there will be strong use cases to use the tokens on either network.
+
+There is no limit on the total. Hypothetically, the entire circulating supply can be bridged, though this is unlikely happen as there will be strong use cases to use the tokens on either network.
+
+However, there are daily quotas:
+
- Daily limit: 100,000 tokens
- Maximum per tx: 10,000 tokens
- Minimum per tx: 1 token
## Can any token be bridged over?
-During the trial period only whitelisted tokens can cross the bridge. The federation is the responsible of adding or removing tokens to the whitelist. When the trial period is over and we move to a fully decentralized bridge the whitelist will be removed.
+
+During the trial period, only whitelisted tokens can cross the bridge. The federation is responsible for adding and removing tokens from the whitelist. When the trial period is over, and we move to a fully decentralized bridge, the whitelist will be removed.
## What are the fees for converting original tokens to Side Tokens and vice-versa? Who will be paying these fees?
-The federation is paying and sponsoring the fees for the multiple transactions during the trial period. This will change after the trial period is complete and the token bridge change from a federated schema to a fully decentralized one. Users will need to pay a small amount of gas fee when using Metamask for to submit their transactions.
+
+The federation is paying and sponsoring the fees for the multiple transactions during the trial period. This will change after the trial period is complete, and the token bridge changes from a federated schema to a fully decentralized one. Users will need to pay a small amount of gas fee when using Metamask for to submit their transactions.
## How many confirmations are required to convert the original tokens to Side tokens and vice-versa?
-There will 15 confirmations. On the POA mainnet and 15 confirmations on the Ethereum network. On Sokol testnet and Kovan testnet, the test bridge will have 2 confirmations.
+
+- 120 confirmations are necessary on the RSK Mainnet, and 120 confirmations on the Ethereum Mainnet.
+- 10 confirmations are necessary on the RSK Testnet, and 10 confirmations on the Ethereum Kovan Testnet.
## How does the Token Bridge work?
-The TokenBridge functionality is quite unique yet simple to understand. The ratio of tokens during network transfer always remains 1:1 and behaves in the following manner:
+
+The Token Bridge functionality is quite unique, yet simple to understand. The ratio of tokens during network transfer always remains 1:1 and behaves in the following manner:
When original tokens are moved to the other network
- Original tokens are locked in the Token Bridge smart contract
-- Side Tokens are minted and can move freely on the Ethereum network
+- Side Tokens are minted to the same address that originally called the bridge
When Side Tokens are moved back from the other network
- Side Tokens are burned
-- Original tokens are unlocked in the Bridge smart contract
+- Original tokens are unlocked in the Token Bridge smart contract and transfer to the same address that originally called the bridge
diff --git a/docs/images/token-bridge-diagram.png b/docs/images/token-bridge-diagram.png
new file mode 100644
index 000000000..006dc5261
Binary files /dev/null and b/docs/images/token-bridge-diagram.png differ
diff --git a/federator/.gitignore b/federator/.gitignore
index 780aedd48..4197b02c6 100644
--- a/federator/.gitignore
+++ b/federator/.gitignore
@@ -4,5 +4,4 @@ development.json
test.json
config/federator.key
federator.log
-db/
test/lib/*.txt
diff --git a/federator/README.md b/federator/README.md
index ef41b3c5a..d25a78a08 100644
--- a/federator/README.md
+++ b/federator/README.md
@@ -14,3 +14,55 @@ To run an integration test use `npm run integrationTest`. The integration test w
In order to test with multiple federators, ensure they're added as members of the Federation contract and pass their private keys as a comma separated string for both chains as arguments of the integration test script. For instance:
`node integrationTest.js "privKeyM1, privKeyM2, privKeyMN" "privKeyS1, privKeyS2, privKeySN"`
+## Run a Federator
+
+### config
+To run the federator using Docker first, go to the /federator/config folder and rename `config.sample.js` to `config.js`. In that file you will dedcide the networks the federate must be listening, for example for the bridge in testnet a federator config.js will look like
+
+```json
+module.exports = {
+ mainchain: require('./rsktestnet-kovan.json'),
+ sidechain: require('./kovan.json'),
+ runEvery: 1, // In minutes,
+ confirmations: 10,// Number of blocks before processing it,
+ privateKey: require('federator.key'),
+ storagePath: './db'
+}
+```
+
+where the mainchain for example is rsktestnet and the sidechain is kovan, the .json files are in the /federator/config folder and includes the addresses of the contracts in that network and the block number when they where deployed.
+The order of sidechain and mainchain is not important is just which one is going to be checked first, as federators are bi directionals.
+Inside the .json files there is also the host to that network, for example this is the rsktestnet-kovan.json
+
+```json
+{
+ "bridge": "0x684a8a976635fb7ad74a0134ace990a6a0fcce84",
+ "federation": "0x36c893a955399cf15a4a2fbef04c0e06d4d9b379",
+ "testToken": "0x5d248f520b023acb815edecd5000b98ef84cbf1b",
+ "multisig": "0x88f6b2bc66f4c31a3669b9b1359524abf79cfc4a",
+ "allowTokens": "0x952b706a9ab5fd2d3b36205648ed7852676afbe7",
+ "host": "",
+ "fromBlock": 434075
+}
+```
+
+You need to change `""` for the url of your node for that network and the json rpc port. `Remember to do it for both networks`.
+Also you need to create a `federetaros.key` file with the federator private in it.
+
+### Latest block
+The federator will use the block number in `./federator/db/latestBlock.txt` for the main chain and `./federator/db/side-fedlatestBlock.txt` for the side chain as starting point. This is important as the federator will increase the number each time it successfully polls for blocks, and indicates the last block run.
+If this files don't exist, the program will automatically create them using the `config.fromBlock` number. This is ok, but the default config number is the creation of the contract and may be too far from the current block number, having a negative impact in performance even preventing the program from running. This is way it should be as closest as the current block number minus the confirmations blocks as posible.
+
+### Docker image
+Once you have changed this configurations create the **docker image from the root folder** using.
+`docker build . -t fed-tokenbridge`
+
+
+Then run :
+```docker run --rm \
+ --network host \
+-v $PWD/federator/config:/app/federator/config \
+-v $PWD/federator/db:/app/federator/db \
+--name=fed-tokenbridge \
+fed-tokenbridge:latest```
+to start the image.
diff --git a/federator/db/lastBlock.txt b/federator/db/lastBlock.txt
new file mode 100644
index 000000000..56a6051ca
--- /dev/null
+++ b/federator/db/lastBlock.txt
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/federator/db/side-fed/lastBlock.txt b/federator/db/side-fed/lastBlock.txt
new file mode 100644
index 000000000..56a6051ca
--- /dev/null
+++ b/federator/db/side-fed/lastBlock.txt
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/federator/integrationTest/transfer.js b/federator/integrationTest/transfer.js
index 94c5ddefd..537be6417 100644
--- a/federator/integrationTest/transfer.js
+++ b/federator/integrationTest/transfer.js
@@ -42,9 +42,11 @@ async function run() {
await transactionSender.sendTransaction(bridgeAddress, data, 0, config.privateKey);
//Wait for confirmations
- let waitBlocks = config.confirmationsfirmations;
+ let waitBlocks = config.confirmations;
logger.debug(`Wait for ${waitBlocks} blocks`);
await utils.waitBlocks(rskWeb3, waitBlocks);
+ logger.debug(`Wait for poll ${config.runEvery} minutes`);
+ await utils.sleep(config.runEvery * 60 * 1000);
logger.debug('get the side token address');
let sideBridgeContract = new ethWeb3.eth.Contract(abiBridge, config.sidechain.bridge);
diff --git a/federator/src/lib/Federator.js b/federator/src/lib/Federator.js
index c8df38a1d..1350b51f1 100644
--- a/federator/src/lib/Federator.js
+++ b/federator/src/lib/Federator.js
@@ -53,10 +53,10 @@ module.exports = class Federator {
fromBlock,
toBlock
});
- if (!logs) return;
+ if (!logs) throw new Error('Failed to obtain the logs');
this.logger.info(`Found ${logs.length} logs`);
- await this._processLogs(logs);
+ await this._processLogs(logs, toBlock);
return true;
} catch (err) {
@@ -71,12 +71,11 @@ module.exports = class Federator {
}
}
- async _processLogs(logs = []) {
+ async _processLogs(logs, toBlock) {
try {
- let lastBlockNumber = null;
const transactionSender = new TransactionSender(this.sideWeb3, this.logger);
const from = await transactionSender.getAddress(this.config.privateKey);
-
+
for(let log of logs) {
this.logger.info('Processing event log:', log);
@@ -110,11 +109,8 @@ module.exports = class Federator {
} else {
this.logger.debug(`Block: ${log.blockHash} Tx: ${log.transactionHash} token: ${symbol} was already processed`);
}
-
- lastBlockNumber = log.blockNumber;
}
-
- this._saveProgress(this.lastBlockPath, lastBlockNumber);
+ this._saveProgress(this.lastBlockPath, toBlock);
return true;
} catch (err) {
diff --git a/federator/src/services/EventCreator.js b/federator/src/services/EventCreator.js
deleted file mode 100644
index 5a73c94e2..000000000
--- a/federator/src/services/EventCreator.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const Web3 = require('web3');
-
-const abiBridge = require('../../abis/Bridge_v0.json');
-const TransactionSender = require('../../lib/TransactionSender.js');
-const CustomError = require('../../lib/CustomError.js');
-
-module.exports = class RskToEth {
- constructor(config, logger) {
- this.config = config;
- this.logger = logger;
-}
-
- async run() {
- try {
- let rskWeb3 = new Web3(this.config.rsk.host);
- let transactionSender = new TransactionSender(rskWeb3, this.logger);
- let bridgeAddress = this.config.rsk.bridge;
- let bridgeContract = new rskWeb3.eth.Contract(abiBridge, bridgeAddress);
- let result = await bridgeContract.methods.emitEvent().call();
- if(result) {
- this.logger.info('Preparing to emit the cross event');
- let data = bridgeContract.methods.emitEvent().encodeABI();
- await transactionSender.sendTransaction(bridgeAddress, data, 0, this.config.rsk.privateKey);
- return true;
- } else {
- this.logger.debug('Conditions are not met to emmit the event');
- return false;
- }
- } catch(err) {
- this.logger.error(new CustomError('Exception Creating RSK Event', err));
- process.exit();
- }
- }
-
-}