https://docs.frax.finance/frax-ether/overview.
git clone https://github.com/FraxFinance/frxETH-public.git --recurse-submodules --remote-submodules
- Install foundry
forge install
git submodule update --init --recursive
4a)cd ./lib/ERC4626 && git checkout main
. This should switch it tocorddry
's fork.- (Optional) Occasionally update / pull your submodules to keep them up to date.
git submodule update --recursive --remote
- Create your own .env and copy SAMPLE.env into there. Sample mainnet validator deposit keys are in test/deposit_data-TESTS-MAINNET.json if you need more.
- You don't need to add PRIVATE_KEY, ETHERSCAN_KEY, or FRXETH_OWNER if you are not actually deploying on live mainnet
Manually, forced
forge build --force
- If you want to add more fuzz cycles, edit foundry.toml
- Foundry cheatcodes
Most cases
source .env && forge test -vv
If you need to fork mainnet
source .env && forge test --fork-url $MAINNET_RPC_URL -vv
If you need to fork mainnet, single test contract
source .env && forge test --fork-url $MAINNET_RPC_URL -vv --match-path ./test/frxETHMinter.t.sol
Verbosely test a single contract while forking mainnet
or source .env && forge test --fork-url $MAINNET_RPC_URL -m test_frxETHMinter_submitAndDepositRegular -vvvvv
for single test verbosity level 5
tsx validate-msig-add-validators.ts
DepositDataToCalldata: SEE THE DepositDataToCalldata.s.sol FILE ITSELF FOR INSTRUCTIONS
- Install slither
- Slither a single contract
slither ./src/sfrxETH.sol --solc-remaps "openzeppelin-contracts=lib/openzeppelin-contracts ERC4626=lib/ERC4626/src solmate=lib/solmate/src"
- Deploy frxETH.sol
- Deploy sfrxETH.sol
- Deploy frxETHMinter.sol
- Add the frxETHMinter as a valid minter for frxETH
- (Optional, depending on how you want to test) Add some validators to frxETHMinter
source .env && forge create src/frxETH.sol:frxETH --private-key $PRIVATE_KEY --rpc-url $GOERLI_RPC_URL --verify --optimize --etherscan-api-key $ETHERSCAN_KEY --constructor-args $FRXETH_OWNER $TIMELOCK_ADDRESS
Goerli
source .env && forge script script/deployGoerli.s.sol:Deploy --rpc-url $GOERLI_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY
Mainnet
source .env && forge script script/deployMainnet.s.sol:Deploy --rpc-url $MAINNET_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY
Sometimes the deploy scripts above fail with Etherscan's verification API. In that case, use:
forge flatten src/frxETHMinter.sol -o flattened.sol
Then do
sed -i '/SPDX-License-Identifier/d' ./flattened.sol && sed -i '/pragma solidity/d' ./flattened.sol && sed -i '1s/^/\/\/ SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.0;\n\n/' flattened.sol
To make new dependencies play nicely with VSCode:
forge remappings > remappings.txt
Parent contract for frxETH.sol. Has EIP-712/EIP-2612 permit capability, is burnable, and has an array of authorized minters. Is also owned.
Basically the same as ERC20PermitPermissionedMint.sol
Authorized minter for frxETH. Users deposit ETH for frxETH. It then deposits that ETH into ETH 2.0 staking validators to earn yield. It can also withhold part of the ETH deposit for future use, such as to earn yield in other places to supplement the ETH 2.0 staking yield.
Keeps track of available validators to add batches of 32 ETH to. Contains various array manipulations. It is assumed that validator checks for validity, as well as ordering in the array, are done off-chain to save gas beforehand.
Autocompounding vault token for frxETH. Users deposit their frxETH for sfrxETH. Adheres to ERC4626/xERC4626. Any rewards earned externally, such as from ETH 2.0 staking, are converted to frxETH then sent here. After that happens, the exchange rate / pricePerShare for the sfrxETH token increases and sfrxETH hodlers can exchange their sfrxETH tokens for more frxETH than they initially put in (this is their rewards). Has EIP-712/EIP-2612 permit capability.
Already audited several times.
Official Ethereum 2.0 deposit contract.
Synthetix.io created.
Only used for testing, so no need to audit.
Openzeppelin created contracts are already extensively audited.
xTRIBE, which is xERC4626.sol based and has some functions that sfrxETH.sol uses, has two known medium severity corner case issues M-01 and M-02
No checking for valid validator pubkeys, signatures, etc are done here. They are assumed to be done off chain before they are added. However, the official ETH 2.0 DepositContract.sol DOES do checks and will revert if something is wrong. It is assumed that the team, or the manager(s) of the OperatorRegistry.sol contract will remove/replace the offending invalid validators.
- frxETH Repository: https://github.com/FraxFinance/frxETH-public
- 5 Non-library contracts in the scope
- 365 Total sLoC in scope.
- Contracts use inheritance, most of the parents are time/battle tested Openzeppelin or other contracts
- Most public interaction will be with frxETHMinter.sol, then sfrxETH.sol
- frxETH.sol conforms to EIP-712/EIP-2612 and ERC-20 standards and uses Openzeppelin and Synthetix.io parents
- sfrxETH.sol conforms to EIP-712/EIP-2612, ERC-4626, and ERC-20 standards
- No novel or unique curve logic or mathematical models
- Not an NFT
- Not an AMM
- Not a fork of a popular project
- Does not use rollups
- Single-chain only