diff --git a/README.md b/README.md index f01e4164..3d2ed4b1 100644 --- a/README.md +++ b/README.md @@ -339,6 +339,7 @@ The scripts automatically calculate these fees and include them in the transacti ## How to release: + * First, deploy on Testnets and make sure all tests are ok. * Create a release branch `release/X.X.X` that starts from the `main` branch. - Note that GitHub environments `arbitrum` and `ethereum` can only be used with `release/*` branches. The `main` branch cannot be used as the CI will not be able to commit deployment artifacts. diff --git a/docs/soldoc/src/README.md b/docs/soldoc/src/README.md index 5667e3eb..3d2ed4b1 100644 --- a/docs/soldoc/src/README.md +++ b/docs/soldoc/src/README.md @@ -4,8 +4,12 @@ This project implements a cross-chain token bridge system for the RLC token usin ## Diagrams and source code docs (soldocs): - - [Diagrams](../../diagrams/) - - [Source code docs](../../soldoc/src/SUMMARY.md) + - [Diagrams](docs/diagrams) + - [Source code docs](docs/soldoc/src/SUMMARY.md) + +## Audits + +* [Halborn audit report](audits/Halborn_iExec-RLC-Multichain-Bridge-Smart-Contract-Security-Assessment-Report.pdf) ## Architecture @@ -116,7 +120,17 @@ The core contracts of the multichain bridge system: ## Usage -### Bridge RLC +### Network Support + +The bridge currently supports: + +#### **Testnets** +- **Ethereum Sepolia** ↔ **Arbitrum Sepolia** + +#### **Mainnets** +- **Ethereum Mainnet** ↔ **Arbitrum Mainnet** + +### Bridge RLC on Testnets A. To send RLC tokens from Ethereum Sepolia to Arbitrum Sepolia: @@ -144,6 +158,20 @@ This will: 2. Send a cross-chain message via LayerZero to Ethereum 3. Release the original RLC tokens from the RLCLiquidityUnifier on Ethereum +### Bridge RLC on Mainnets + +A. To send RLC tokens from Ethereum Mainnet to Arbitrum Mainnet: + +```bash +make send-tokens-to-arbitrum-mainnet +``` + +B. To send RLC tokens from Arbitrum Mainnet back to Ethereum Mainnet: + +```bash +make send-tokens-to-ethereum-mainnet +``` + ## 📊 Code Coverage Analysis ### Generating Coverage Reports @@ -309,8 +337,25 @@ The scripts automatically calculate these fees and include them in the transacti - [Forge Coverage](https://book.getfoundry.sh/reference/forge/forge-coverage) - [iExec Platform Documentation](https://docs.iex.ec/) +## How to release: + + +* First, deploy on Testnets and make sure all tests are ok. +* Create a release branch `release/X.X.X` that starts from the `main` branch. + - Note that GitHub environments `arbitrum` and `ethereum` can only be used with `release/*` branches. The `main` branch cannot be used as the CI will not be able to commit deployment artifacts. +* Commit required changes (salt, ...) +* Go to "Actions" section on GitHub +* Trigger `Deploy contracts` job and choose the correct release branch and the target Github environment. + ## TODO - Use an enterprise RPC URL for `secrets.SEPOLIA_RPC_URL` in Github environment `ci`. - Add git pre-commit hook to format code locally. - Testing Documentation +- Parametrize the following addresses by chain in `config.json`: +``` + "initialAdmin": "0x111165a109feca14e4ad4d805f6460c7d206ead1", + "initialUpgrader": "0x111121e2ec2557f484f65d5b1ad2b6b07b8acd23", + "initialPauser": "0x11113fe3513787f5a4f5f19690700e2736b3056e", +``` +- Clean README.md diff --git a/docs/soldoc/src/src/RLCCrosschainToken.sol/contract.RLCCrosschainToken.md b/docs/soldoc/src/src/RLCCrosschainToken.sol/contract.RLCCrosschainToken.md index df40a552..ee3e951b 100644 --- a/docs/soldoc/src/src/RLCCrosschainToken.sol/contract.RLCCrosschainToken.md +++ b/docs/soldoc/src/src/RLCCrosschainToken.sol/contract.RLCCrosschainToken.md @@ -1,5 +1,5 @@ # RLCCrosschainToken -[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/61326e3abe32aee8683989ab94220c30da0cb2e6/src/RLCCrosschainToken.sol) +[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/93b2d2b8fb41a03ccb6bc3a710204b628f122d69/src/RLCCrosschainToken.sol) **Inherits:** UUPSUpgradeable, AccessControlDefaultAdminRulesUpgradeable, ERC20PermitUpgradeable, ERC20BridgeableUpgradeable @@ -11,8 +11,6 @@ by permitted bridge contracts. To whitelist a token bridge contract, the admin (with `DEFAULT_ADMIN_ROLE`) sends a transaction to grant the role `TOKEN_BRIDGE_ROLE` to the bridge contract address using `grantRole` function. -TODO upgrade openzeppelin packages when the audited version of ERC20BridgeableUpgradeable -is released. ## State Variables @@ -116,7 +114,7 @@ an account with the UPGRADER_ROLE.* ```solidity -function _authorizeUpgrade(address newImplementation) internal override onlyRole(UPGRADER_ROLE); +function _authorizeUpgrade(address) internal override onlyRole(UPGRADER_ROLE); ``` ### _checkTokenBridge @@ -129,12 +127,6 @@ Checks if the caller is a trusted token bridge that is allowed by iExec to call ```solidity -function _checkTokenBridge(address caller) internal view override; +function _checkTokenBridge(address) internal view override onlyRole(TOKEN_BRIDGE_ROLE); ``` -**Parameters** - -|Name|Type|Description| -|----|----|-----------| -|`caller`|`address`|The address of the caller that is trying to mint or burn tokens.| - diff --git a/docs/soldoc/src/src/RLCLiquidityUnifier.sol/contract.RLCLiquidityUnifier.md b/docs/soldoc/src/src/RLCLiquidityUnifier.sol/contract.RLCLiquidityUnifier.md index cc9a71b3..0cb69df3 100644 --- a/docs/soldoc/src/src/RLCLiquidityUnifier.sol/contract.RLCLiquidityUnifier.md +++ b/docs/soldoc/src/src/RLCLiquidityUnifier.sol/contract.RLCLiquidityUnifier.md @@ -1,5 +1,5 @@ # RLCLiquidityUnifier -[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/61326e3abe32aee8683989ab94220c30da0cb2e6/src/RLCLiquidityUnifier.sol) +[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/93b2d2b8fb41a03ccb6bc3a710204b628f122d69/src/RLCLiquidityUnifier.sol) **Inherits:** UUPSUpgradeable, AccessControlDefaultAdminRulesUpgradeable, [IRLCLiquidityUnifier](/src/interfaces/IRLCLiquidityUnifier.sol/interface.IRLCLiquidityUnifier.md), IERC7802 @@ -9,7 +9,8 @@ the minting and burning of tokens on the RLC token contract. All bridges should interact with this contract to perform RLC transfers. The implementation is inspired by the OpenZeppelin ERC20Bridgeable contract without being an ERC20 token itself. Functions are overridden to lock/unlock -tokens on an external ERC20 contract.* +tokens on an external ERC20 contract. ERC20Bridgeable is not used directly +because it embarks the ERC20 token logic, which is not needed here.* ## State Variables diff --git a/docs/soldoc/src/src/bridges/layerZero/IexecLayerZeroBridge.sol/contract.IexecLayerZeroBridge.md b/docs/soldoc/src/src/bridges/layerZero/IexecLayerZeroBridge.sol/contract.IexecLayerZeroBridge.md index 81a19d26..8cb67009 100644 --- a/docs/soldoc/src/src/bridges/layerZero/IexecLayerZeroBridge.sol/contract.IexecLayerZeroBridge.md +++ b/docs/soldoc/src/src/bridges/layerZero/IexecLayerZeroBridge.sol/contract.IexecLayerZeroBridge.md @@ -1,5 +1,5 @@ # IexecLayerZeroBridge -[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/61326e3abe32aee8683989ab94220c30da0cb2e6/src/bridges/layerZero/IexecLayerZeroBridge.sol) +[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/93b2d2b8fb41a03ccb6bc3a710204b628f122d69/src/bridges/layerZero/IexecLayerZeroBridge.sol) **Inherits:** UUPSUpgradeable, AccessControlDefaultAdminRulesUpgradeable, OFTCoreUpgradeable, [DualPausableUpgradeable](/src/bridges/utils/DualPausableUpgradeable.sol/abstract.DualPausableUpgradeable.md), [IIexecLayerZeroBridge](/src/interfaces/IIexecLayerZeroBridge.sol/interface.IIexecLayerZeroBridge.md) @@ -205,13 +205,29 @@ function token() external view returns (address); |``|`address`|The address of the RLC token contract| -### owner +### renounceOwnership + +*Overridden to prevent ownership renouncement. +AccessControlDefaultAdminRulesUpgradeable is used to manage ownership.* + + +```solidity +function renounceOwnership() public pure override; +``` + +### transferOwnership + +*Overridden to prevent ownership transfer. +AccessControlDefaultAdminRulesUpgradeable is used to manage ownership.* + + +```solidity +function transferOwnership(address) public pure override; +``` -Returns the owner of the contract +### owner -*This override resolves the conflict between OwnableUpgradeable and -AccessControlDefaultAdminRulesUpgradeable, both of which define owner(). -We use the OwnableUpgradeable version for consistency.* +Returns the owner of the contract which is also the default admin. ```solidity @@ -225,8 +241,21 @@ function owner() |Name|Type|Description| |----|----|-----------| -|``|`address`|The address of the current owner| +|``|`address`|The address of the current owner and default admin| + + +### _acceptDefaultAdminTransfer +Accepts the default admin transfer and sets the owner to the new admin. + +*This ensures the state variable `OwnableUpgradeable._owner` is set correctly after the default +admin transfer. Even though `OwnableUpgradeable._owner` is not used in `owner()` accessor, we chose +to update it for consistency purposes.* + + +```solidity +function _acceptDefaultAdminTransfer() internal override; +``` ### _debit diff --git a/docs/soldoc/src/src/bridges/utils/DualPausableUpgradeable.sol/abstract.DualPausableUpgradeable.md b/docs/soldoc/src/src/bridges/utils/DualPausableUpgradeable.sol/abstract.DualPausableUpgradeable.md index 0f3a560a..ab89c45d 100644 --- a/docs/soldoc/src/src/bridges/utils/DualPausableUpgradeable.sol/abstract.DualPausableUpgradeable.md +++ b/docs/soldoc/src/src/bridges/utils/DualPausableUpgradeable.sol/abstract.DualPausableUpgradeable.md @@ -1,5 +1,5 @@ # DualPausableUpgradeable -[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/61326e3abe32aee8683989ab94220c30da0cb2e6/src/bridges/utils/DualPausableUpgradeable.sol) +[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/93b2d2b8fb41a03ccb6bc3a710204b628f122d69/src/bridges/utils/DualPausableUpgradeable.sol) **Inherits:** PausableUpgradeable diff --git a/docs/soldoc/src/src/interfaces/IIexecLayerZeroBridge.sol/interface.IIexecLayerZeroBridge.md b/docs/soldoc/src/src/interfaces/IIexecLayerZeroBridge.sol/interface.IIexecLayerZeroBridge.md index ecec8cf0..f57b6a9b 100644 --- a/docs/soldoc/src/src/interfaces/IIexecLayerZeroBridge.sol/interface.IIexecLayerZeroBridge.md +++ b/docs/soldoc/src/src/interfaces/IIexecLayerZeroBridge.sol/interface.IIexecLayerZeroBridge.md @@ -1,5 +1,5 @@ # IIexecLayerZeroBridge -[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/61326e3abe32aee8683989ab94220c30da0cb2e6/src/interfaces/IIexecLayerZeroBridge.sol) +[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/93b2d2b8fb41a03ccb6bc3a710204b628f122d69/src/interfaces/IIexecLayerZeroBridge.sol) ## Functions @@ -47,3 +47,10 @@ Unpauses the `_debit` function, allowing outbound transfers again. function unpauseOutboundTransfers() external; ``` +## Errors +### OperationNotAllowed + +```solidity +error OperationNotAllowed(string message); +``` + diff --git a/docs/soldoc/src/src/interfaces/IRLCLiquidityUnifier.sol/interface.IRLCLiquidityUnifier.md b/docs/soldoc/src/src/interfaces/IRLCLiquidityUnifier.sol/interface.IRLCLiquidityUnifier.md index 53ad7ef0..ab7380c1 100644 --- a/docs/soldoc/src/src/interfaces/IRLCLiquidityUnifier.sol/interface.IRLCLiquidityUnifier.md +++ b/docs/soldoc/src/src/interfaces/IRLCLiquidityUnifier.sol/interface.IRLCLiquidityUnifier.md @@ -1,5 +1,5 @@ # IRLCLiquidityUnifier -[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/61326e3abe32aee8683989ab94220c30da0cb2e6/src/interfaces/IRLCLiquidityUnifier.sol) +[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/93b2d2b8fb41a03ccb6bc3a710204b628f122d69/src/interfaces/IRLCLiquidityUnifier.sol) *Interface for the RLC Liquidity Unifier contract. This interface defines the contract that is used to centralize the RLC liquidity diff --git a/docs/soldoc/src/src/interfaces/ITokenSpender.sol/interface.ITokenSpender.md b/docs/soldoc/src/src/interfaces/ITokenSpender.sol/interface.ITokenSpender.md index 5869e7ff..f981c9b5 100644 --- a/docs/soldoc/src/src/interfaces/ITokenSpender.sol/interface.ITokenSpender.md +++ b/docs/soldoc/src/src/interfaces/ITokenSpender.sol/interface.ITokenSpender.md @@ -1,5 +1,5 @@ # ITokenSpender -[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/61326e3abe32aee8683989ab94220c30da0cb2e6/src/interfaces/ITokenSpender.sol) +[Git Source](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/93b2d2b8fb41a03ccb6bc3a710204b628f122d69/src/interfaces/ITokenSpender.sol) *See [RLCrosschainToken-approveAndCall](/src/RLCCrosschainToken.sol/contract.RLCCrosschainToken.md#approveandcall). An interface for a contract that can receive approval from an ERC20 token and execute diff --git a/src/RLCCrosschainToken.sol b/src/RLCCrosschainToken.sol index 0285428e..73b73b82 100644 --- a/src/RLCCrosschainToken.sol +++ b/src/RLCCrosschainToken.sol @@ -21,9 +21,6 @@ import {ITokenSpender} from "./interfaces/ITokenSpender.sol"; * To whitelist a token bridge contract, the admin (with `DEFAULT_ADMIN_ROLE`) sends * a transaction to grant the role `TOKEN_BRIDGE_ROLE` to the bridge contract address * using `grantRole` function. - * - * TODO upgrade openzeppelin packages when the audited version of ERC20BridgeableUpgradeable - * is released. */ contract RLCCrosschainToken is UUPSUpgradeable,