- Introduction
- Installation
- Testing
- Contract Requirements
- Flow Diagram
- Security Considerations
- Contract Docs
- Deployment Script
- External Dependencies
- References
The FusionLock contract enables users to deposit ERC20 tokens and Ether for a specified period. Once the withdrawal term starts, users can bridge their funds to Layer 2 or withdraw on Layer 1. The contract supports pausing functionality and grants the owner the ability to manage withdrawal start times, as well as token allowances.
Prerequisite: foundry needs to be installed.
git clone --recurse-submodules https://github.com/bob-collective/fusion-lock.git
cd fusion-lock/
forge build
- Fuzz testing and unit testing have been done for contract functionality and can be found in the test folder.
- To run tests use the following forge command:
forge test
- To run slither static analyzer with the script, conda needs to be pre-installed along with python version
3.11.6
. - Command to run the script, the output will be displayed in terminal:
chmod +x automated-test/slither.sh
- To run mythril static analyzer with the script, conda needs to be pre-installed along with python version
3.11.6
. - Command to run the script, the output will be displayed in terminal:
chmod +x automated-test/mythril.sh
These are the requirements on which the smart contract is designed.
For Owner:
- The owner of the FusionLock contract will be a Safe multisig.
- The owner can pause and resume all user functionalities. An exception is made for
withdrawDepositsToL1
which is made unpausable to prevent the owner from being able to take user's funds hostage. - The owner can reduce
withdrawalStartTime
. - The owner can modify the global
bridgeProxyAddress
. - The owner can set a L1 bridge override for any of the allowed tokens.
- The owner can modify the
l2TokenAddress
, which is mapped to thel1TokenAddress
. - The owner can allow deposits of any ERC20 token. The ones that are planned for use are listed in the deployment script. For convenience, the tokens are also listed below, but the script is considered the source of truth.
- If the contract contains higher ERC20 token amounts than have deposited (e.g. if bridging were to fail, then the owner can withdraw the tokens to a specified address. This is an extra precaution against tokens getting stuck in the contract.
For User:
- The user locks funds within the contract through a deposit.
- The user is allowed to make multiple deposits; redeposits are permitted.
- All users will be able to bridge to L2 if the current block timestamp is greater than or equal to
withdrawalStartTime
- All users will be able to withdraw to L1 if the current block timestamp is greater than or equal to
withdrawalStartTime
Note:
- Only one user functionality is active at any given time, either deposit or withdraw.
- The native token ETH is allowed to be deposited by default.
The flow diagram illustrates an example contract timeline.
Note: All timestamps are provided for reference; different timestamps will be used during deployment.
Operations Allowed in Timeframes
The following owner operations are allowed at any time:
- Can pause user functionality.
- Can set global bridge proxy address
- Can change the L2 address of any token.
- Can set a L1 bridge override for any token.
1) During deposit
For Owner:
- Can allow deposits of any ERC20 tokens, ideally taken from a list.
- Can reduce the withdrawal start time.
For User:
- Deposit for ETH and ERC20 tokens allowed.
2) After withdrawal starts
For User:
- Withdrawal on Layer 1 for ETH and ERC20 tokens allowed.
- Withdrawal on Layer 2 for ETH and ERC20 tokens allowed.
- Dependency on the owner to act rationally as it holds power to stop most user functionality. However, the owner can't pause withdrawals to L1 or transfer user funds.
- The owner is trusted to set valid bridge proxy address, as well as valid L2 token addresses.
block.timestamp
used extensively in the contract, knowing the limitation discussed in yellow paper. As it is the best approach.- All the funds are held in a smart contract; a user contract wallet design was discussed by the team but skipped due to the issues discussed here
- If bridging fails, then the owner can withdraw the ERC20 tokens involved to an arbitrary account. The owner is trusted to refund the tokens to the user if this were to happen. Solutions requiring less trust are possible, but would increase the complexity of the contract too much.
- NatSpec format is used to write the contract documentation.
- To generate and build a markdown book for the contract, use the following command:
forge doc --serve
- Before running the deployment script, ensure the environment variables are correctly set:
git clone --recurse-submodules https://github.com/bob-collective/fusion-lock.git
cd fusion-lock/
./deploy-contract.sh
BOB is a Bitcoin-augmented rollup bringing experimentation and freedom of choice to builders to make a real-world impact. BOB's vision is to onboard the next billion users to Bitcoin.