Beanstalk is a decentralized credit based algorithmic stablecoin protocol that is built on Ethereum.
Technical documentation is a WIP. Current Draft is available here: https://gist.github.com/leonardo-fibonacci/268bb316c4c5ac08bcbc431927998a51
Contract | Addresss |
---|---|
Bean | 0xDC59ac4FeFa32293A95889Dc396682858d52e5Db |
Beanstalk | 0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5 |
UniswapV2 BEAN:ETH Pool | 0x87898263B6C5BABe34b4ec53F22d98430b91e371 |
Curve BEAN:3CRV Metapool | 0x3a70DfA7d2262988064A2D051dd47521E43c9BdD |
Curve BEAN:LUSD Plain Pool | 0xD652c40fBb3f06d6B58Cb9aa9CFF063eE63d465D |
Beanstalk Contract Owner | 0xefd0E9ff0C4E1Bee55Db53FDD1FAD6F6950CeD0b |
Beanstalk Farms Multisig | 0x21DE18B6A8f78eDe6D16C50A167f6B222DC08DF7 |
Bean Sprout Multisig | 0xb7ab3f0667eFF5e2299d39C23Aa0C956e8982235 |
Development Budget 1 | 0x83A758a6a24FE27312C1f8BDa7F3277993b64783 |
Marketing Budget 1 | 0xAA420e97534aB55637957e868b658193b112A551 |
Beanstalk Farms Budget | 0x21DE18B6A8f78eDe6D16C50A167f6B222DC08DF7 |
Bean Sprout Budget | 0xb7ab3f0667eFF5e2299d39C23Aa0C956e8982235 |
BeaNFT Genesis | 0xa755A670Aaf1FeCeF2bea56115E65e03F7722A79 |
BeaNFT Winter | 0x459895483556dad32526efa461f75e33e458d9e9 |
The Beanstalk smart contract is a multi-facet proxy as it implements EIP-2535. Thus, the Beanstalk contract pulls in functions from a variety of different contracts (called facets in the EIP-2535 documentation) that are all capable of sharing the same state object.
The following are the different facets Beanstalk uses:
The following facets are part of the diamond functionality:
Contract | Addresss |
---|---|
DiamondCutFacet | 0xDFeFF7592915bea8D040499E961E332BD453C249 |
DiamondLoupeFacet | 0xB51D5C699B749E0382e257244610039dDB272Da0 |
OwnershipFacet | 0x0176D95fd451353F3543A4542e667C62b673621a |
- clone the repository
- run
cd protocol
to enter the protocol repository - run
npm install
- run
npx hardhat compile
- make sure you are in the
protocol
repository - run
npm test
to run all coverage tests - run
npx hardhat coverage
to run all coverage tests and generate a coverage report
As Beanstalk implements EIP-2535, Beanstalk is upgraded through a diamondCut
function call.
There are two different ways a diamondCut
can apply code to Beanstalk:
- adding/replacing/removing functions
- Functions being added/replaced are implemented in smart contracts referred to as
facets
. Facets are no different than a normal smart contract with callable functions. In order to share a state, Facets can only define 1 internal state variable: TheAppStorage
struct defined inAppStorage.sol
.
- Functions being added/replaced are implemented in smart contracts referred to as
- calling the
init
function of a smart contract- This is a one time action and will be called when the
diamondCut
is executed. There can be 1init
call perdiamondCut
.
- This is a one time action and will be called when the
For this tutorial, we are going to create a new facet called SampleFacet
. In your own implementation replace iterations of the word Sample
with the name of the Facet you want to create.
- make sure you are in the
protocol
repository - in
protocol/farm/facets/
, create a new folder calledSampleFacet
- within the
SampleFacet
folder create a file calledSampleFacet.sol
. - implement your faucet. You can use
SampleFacet.sol
inprotocol/samples
as a template for a basis faucet. Note that facets can only haveAppStorage
as an internal state variable or there will be issues with accessingAppStorage
. - modify the
deploy
function inscripts/deploy
to include your new facet, so that thefaucet
will be deployed with the Beanstalk diamond.
There are a couple of steps that must be done before we can fork mainnet and upgrade Bips/test Bip upgrades
-
include the following code in the networks section of the hardhat.config.js, where ALCHEMY_URL is your mainnet url. We recommend using Alchemy for this. The blockNumber is optional, but we recommend to be one that is close to the current block number but not too close.
forking: { url: <RPC_URL>, blockNumber: <BLOCK_NUMBER> },
localhost: { chainId: 1337, url: "http://127.0.0.1:8545", forking: { url: <RPC_URL>, blockNumber: <BLOCK_NUMBER> }, },
-
include as in imports section
const BEANSTALK = "0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5"; const ownerFacet = await ethers.getContractAt('OwnershipFacet', BEANSTALK); const owner = await ownerFacet.owner(); const { upgradeWithNewFacets } = require('./scripts/diamond.js')
-
Lastly, include the tasks required for upgrading above module.exports:
task("upgrade", "Commits a bip", async() => { await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [owner], }); const account = await ethers.getSigner(owner) await upgradeWithNewFacets({ diamondAddress: BEANSTALK, facetNames: [], initFacetName: 'InitEmpty', initArgs: [], bip: false, verbose: true, account: account }); })
-
(this is an example of what bip11 deployment looked like):
await upgradeWithNewFacets({ diamondAddress: BEANSTALK, initFacetName: 'InitBip11', facetNames: ['MarketplaceFacet'], libraryNames: ["LibClaim"], facetLibraries: { "MarketplaceFacet": ["LibClaim"], }, bip: false, verbose: true, account: account });
-
Spin up your mainnet fork node with:
npx hardhat node
-
In another console, execute your tasks by running
npx hardhat upgrade --network localhost
where
upgrade
is where you put the name of your task, in the example above it was named upgrade. -
Now you can test your changes using your local blockchain node that should now have the latest version of beanstalk that you upgraded.
Code Version: 1.16.0
Whitepaper Version 1.9.3