This is a project that can/should be used in all Bao contract projects.
Bao-base has base classes for foundry scripting based deployment - basically for every contract deployable there is a contract that configures it.
It uses lib/bao-factory for deterministic CREATE3 deployments. See the bao-factory README for deployment operations.
These contracts provide ownership and role-based access control but do not behave like OpenZeppelin's equivalents.
- Ownership transfer is one-time only and must complete within 1 hour
- Uses a two-phase pattern:
deployerOwner(initial setup) →pendingOwner(final owner) _initializeOwner(deployerOwner, pendingOwner)sets both;transferOwnership(pendingOwner)completes it- Once transferred, ownership cannot be changed again
- Supports ERC165 interface detection
- Based on Solady's
OwnableRolesbut decoupled from the ownable mechanism - Provides
grantRoles,revokeRoles,hasAllRoles,hasAnyRole - Role constants are defined as
_ROLE_0,_ROLE_1, etc. (bitmask pattern) - Mixes with
BaoOwnableorBaoOwnableTransferrableviaBaoOwnableRoles
Variants: BaoFixedOwnable (hardcoded owner), BaoOwnableTransferrable (allows later transfers).
A UUPS-upgradeable ERC20 with role-gated minting and burning.
- Uses
BaoOwnableRolesfor access control MINTER_ROLEandBURNER_ROLEconstants for role checks- Includes ERC20Permit support
- ERC165 interface detection for
IMintable,IBurnable,IBurnableFrom
A minimal UUPS contract used for emergency pausing via proxy upgrade.
- Upgrade a proxy to
BaoPauser_v1to disable all functionality - Uses
BaoFixedOwnablewith hardcoded Harbor multisig owner - Upgrade back to the original implementation to restore functionality
Abstract contract for sweeping tokens from a contract.
- Provides
sweep(token, amount, receiver)to recover stuck tokens - Uses reentrancy guard and owner check by default
- Override
_checkSweeper()to customize access control
Shared test utilities for Foundry suites. Extend BaoTest instead of Test to get:
assertApprox- pytest-style approximate assertions with absolute and optional relative tolerancesisApprox- boolean version for use in conditionals- BaoFactory deployment helpers and labeled addresses
assertApprox(actual, expected, 1e15); // 0.001 absolute tolerance
assertApprox(actual, expected, 0, 0.01 ether); // 1% relative toleranceInstall this project using
$ forge install baofinance/bao-baseadd this to remappings.txt
@bao/=lib/bao-base/src/
You can/should use config files used here for your project
in package.json
{
"scripts": {
"lint": "solhint 'src/**/*.sol' --config ./lib/bao-base/.solhint.json --disc"
}
}in package.json
{
"scripts": {
"slither": "echo $(which slither) version=$(slither --version) && slither . --config ./lib/bao-base/slither.config.json --exclude-dependencies --fail-pedantic",
"install:slither": "pip3 install slither-analyzer --upgrade"
}
}There is no slither npm package, so you have to install it manually by:
$ yarn install:slitherdo it this way so the github actions can install slither too.
in package.json
{
"scripts": {
"prettier": "prettier --log-level warn '{src,test,script}/**/*.sol'",
"fmt": "yarn prettier --write",
"fmt:check": "yarn prettier --check"
},
"prettier": "./lib/bao-base/prettier.config.js"
}The prettier vscode extension can also access the same config this way.
This git module also provides a standard build and test for solidity.
Put this in your .github/workflows/<name>.yml
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
call_bao-foundry-project:
uses: baofinance/bao-base/.github/workflows/bao-foundry-project.yml@mainThis will call into bao-base's workflow which will execute a standard set of build and test commands.
You will need to set up you package.json so that it has the following:
{
"scripts": {
"test": ...,
"coverage": ...,
"sizes": ...,
"gas": ...,
"fmt:check": ...,
"lint": ...
}
}This workflow can be executed locally. Add this to your package.json
{
"scripts": {
"pre-push": "gh act -P ubuntu-latest=-self-hosted",
"install:act": "gh extension install https://github.com/nektos/gh-act"
}
}There is no npm package for this, so you have to install it manually by:
$ yarn install:actThe local execution uses your .env file which is not available on github so you need to add any API keys into you github repo.
Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
Foundry consists of:
- Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
- Chisel: Fast, utilitarian, and verbose solidity REPL.
$ yarn # install node dependencies
$ yarn test # build and run tests, also installs git submodules
$ yarn coverage # generates test coverage.txt - this should go in git
$ yarn sizes # generates test sizes.txt - this should go in git
$ yarn gas # generates gas.txt - this should go in gitWe store those file coverage.txt, sizes.txt, and gas.txt in git so that they can be monitored for regressions. Watch this space for something better than the textual diff that git gives you.
$ yarn fmt # uses prettier
$ yarn slither
$ yarn lint # uses solhintYou can run all the commands above before you commit and certainly before you push by:
$ yarn pre-push