Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FROZEN] Installation and documentation update #99

Closed
wants to merge 12 commits into from
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/bread-token-v2"]
path = lib/bread-token-v2
url = git@github.com:BreadchainCoop/bread-token-v2.git
url = https://github.com/BreadchainCoop/bread-token-v2.git
[submodule "lib/openzeppelin-foundry-upgrades"]
path = lib/openzeppelin-foundry-upgrades
url = https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Contributions to this repo are expected to adhere to the [Biconomy Solidity Styl

## Usage

### Clone
```shell
$ git clone [email protected]:BreadchainCoop/breadchain.git --recursive
```
### Build

```shell
Expand All @@ -32,10 +36,18 @@ $ forge snapshot
```

### Test
For validating that tests are working run

```shell
$ forge test --fork-url "https://rpc.gnosis.gateway.fm" -vvvv --fuzz-runs 1
```

For a full run of tests run the following command. Note that the command may take upwards of 8 minutes to execute.

```shell
$ forge test --fork-url "https://rpc.gnosis.gateway.fm" -vvvv
```

### Deploy

```shell
Expand All @@ -55,4 +67,7 @@ forge script script/deploy/DeployYieldDistributor.s.sol:DeployYieldDistributor -
1. Amend the `data` variable in `script/upgrades/UpgradeYieldDistributor.s.sol` to match desired data
2. run `forge clean && forge build && forge script script/upgrades/UpgradeYieldDistributor.s.sol --sig "run(address)" <proxy_address> --rpc-url $RPC_URL --sender <proxy_admin>`

The proxy admin address is configured to be the Breadchain multisig at address `0x918dEf5d593F46735f74F9E2B280Fe51AF3A99ad` and the Yield Distributor proxy address is `0xeE95A62b749d8a2520E0128D9b3aCa241269024b`
The proxy admin address is configured to be the Breadchain multisig at address `0x918dEf5d593F46735f74F9E2B280Fe51AF3A99ad` and the Yield Distributor proxy address is `0xeE95A62b749d8a2520E0128D9b3aCa241269024b`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove this line. First part describes contract state which may change. Second part is deployment info. If anything this should be split into two sections. The multisig address can be added to general info at the top of the README. Then add another section, maybe in table form, that lists production deployments of the contracts contained in the repo, like:

Contract Address
Bread 0xa555d5344f6FB6c65da19e403Cb4c1eC4a1a5Ee3
YieldDistributor 0xeE95A62b749d8a2520E0128D9b3aCa241269024b



Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove one line break.

The development of this project was enabled by a [grant](https://gov.powerpool.finance/t/approved-grant-for-breadchain-cooperative-integrations/2007) from [Powerpool](https://powerpool.finance/).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is necessary either. It's sort of an ambiguous statement and could be misinterpreted. Does it mean the entire Breadchain project was funded by this grant?

89 changes: 89 additions & 0 deletions docs/Bread.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
## What is BREAD?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems weird to have docs for this contract but to not include the contract. Will bring it up at next core meeting.


BREAD is the community currency for the Breadchain ecosystem which exists on Gnosis Chain. All BREAD is created through the [Bread Crowdstaking Application](https://www.notion.so/Crowdstaking-Application-9f233bc2fb1e419ebeb58a2809b21658?pvs=21) which anyone with xDAI on Gnosis Chain is able to use to have some BREAD for themselves.
Copy link
Contributor

@bagelface bagelface Sep 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So whenever I see a fully capitalized name like this, I assume it is referring to the symbol/ticker. I think we should either prepend the $ to any occurrence for consistency personally. Recommended change:

Bread ($BREAD) is the community currency for the Breadchain ecosystem, deployed to the Gnosis Chain network as an ERC20 token. All $BREAD is created through the Bread Crowdstaking Application. Anyone with xDAI on Gnosis Chain can bake $BREAD for themselves, which is referred to as "baking".


```mermaid
Copy link
Contributor

@bagelface bagelface Sep 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we love diagrams, but is this really providing value? I have two problems with it: (1) It's essentially recreating the structure of the contract is a second place, which means it now needs to be maintained in two places. If we change the contract and forget to change this (which in my experience happens A LOT which stuff like this) it actually detracts from peoples understanding of the system. (2) It's not obvious what all the random symbols in this diagram mean, so it makes for a diagram that is sort of impossible to fully understand. Especially without a "key" for the symbols.

The structure of the contract is self documented by the contract code itself.

classDiagram
class Bread {
<<abstract>> ERC20VotesUpgradeable
<<abstract>> OwnableUpgradeable
<<abstract>> IBread

<<abstract>> SafeERC20 for IERC20

+ address yieldClaimer
+ IWXDAI wxDai
+ ISXDAI sexyDai

+ __constructor__()
+ initialize()
+ setYieldClaimer()
+ mint() 💰
+ burn()
+ claimYield()
+ rescueToken()
+ yieldAccrued() 🔍
# _yieldAccrued() 🔍
# _nativeTransfer()
+ transfer()
+ transferFrom()
}

Bread <|-- ERC20VotesUpgradeable : Inheritance
Bread <|-- OwnableUpgradeable : Inheritance
Bread <|-- IBread : Inheritance
Bread .. SafeERC20 : uses IERC20
```

The Crowdstaking Application is a smart contract on Gnosis Chain that accepts a user’s xDAI and turns it into sDAI. In exchange, stakers receive BREAD tokens, minted at a 1-to-1 ratio with the collateralized xDAI.

All of the interest earned on the sDAI is helps fund the collective and its various member projects based on a monthly vote from BREAD holders. The Crowdstaking Application functions as a fundraising engine for the Breadchain Cooperative, while the BREAD token acts as a local currency within the ecosystem, promoting financial sustainability.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove "is" in this line


Additionally, BREAD holders are able to to vote on how the yield generated from the sDAI is distributed among the projects part of the Breadchain Network every month.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some typos; suggested fix:
"...BREAD holders are able to vote on how the yield generated from the sDAI is distributed among the projects that are part of the..."


[Gnosis Chain Deployment](https://gnosisscan.io/token/0xa555d5344f6fb6c65da19e403cb4c1ec4a1a5ee3)

## Technical Breakdown
### Minting
```solidity
1 function mint(address receiver) external payable {
2 // ... validation snippets
3 wxDai.deposit{value: val}();
4 IERC20(address(wxDai)).safeIncreaseAllowance(address(sexyDai), val);
5 sexyDai.deposit(val, address(this));
6
7 _mint(receiver, val);
8
9 // ... delegation snippet
10 }
```
On line 3 the native currency (xDai) of Gnosis Chain gets converted to an ERC20 representation ([wxDai](https://gnosisscan.io/address/0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d)). This is done because in order to lock the xDai.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

last sentence doesn't read correctly; suggested fix:
"This is done to lock the xDai."

It would be helpful for my brain if there was one sentence prefacing this breakdown to explain the whole process more succinctly, GPT suggested:

"The minting process involves converting xDai to wxDai, locking it in the sDai contract to generate yield through the Dai Savings Rate, and minting BREAD tokens as vouchers for the deposited xDai, which can later be redeemed."


[sDai](https://gnosisscan.io/address/0xaf204776c7245bF4147c2612BF6e5972Ee483701) is an automatic mechanism that allows a user to recieve yield from the [Dai Savings Rate](https://blog.makerdao.com/why-the-dai-savings-rate-is-a-game-changer-for-the-defi-ecosystem-and-beyond/) by depositing and locking wxDai. This is how BREAD generates yield.
On line 4 , the Bread contract allows the [sDai contract](https://gnosisscan.io/address/0xaf204776c7245bF4147c2612BF6e5972Ee483701) to take xDai from itself.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we suddenly adding spaces before the commas in this whole section?


On line 5 , the wxDai is deposited and turned into sDai, which is in possession by the BREAD contract.

On line 7 , BREAD is minted to the reciever as a voucher for their deposit. This enables the reciever to redeem their BREAD for the amount of xDai that was deposited.

Lets look at another snippet from the BREAD contract , which is used to calculate how much yield is available for the Breadchain federation.

```solidity
1 function _yieldAccrued() internal view returns (uint256) {
2 uint256 bal = IERC20(address(sexyDai)).balanceOf(address(this));
3 uint256 assets = sexyDai.convertToAssets(bal);
4 uint256 supply = totalSupply();
5 return assets > supply ? assets - supply : 0;
6 }
```
On line 2 , the `bal` variable represents the sDai balance of the Bread contract. This represents how much xDai is locked and earning yield.

In line 3 use the `bal` variable to determine how much xDai the Bread contract is eligible for by burning sDai, and we store that in the `assets` variable. This represents the original xDai locked and any rewards earned.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No there are no commas at all.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: rewrite to read "Line 3 uses the bal variable to determine..."

Also wondering about "rewards earned" - can that be more clear? My understanding is that this is talking about interest earned by the sDai via the DSR


On line 4 we determine how much BREAD is in circulation, and store that in the `supply` variable. This variable represents how much xDai the BREAD contract "owes" to BREAD holders, as they may redeem their BREAD for xDai at a 1:1 ratio.

To understand how much yield the Bread contract has , we first ascertain that by burning all sDai we have enough xDai for BREAD redemptions. While the state is unreachable, this validation is present for safety reasons. Once we are certain of that , the `assets - supply` subtraction in line 5 represents the **total liquid xDai available for claim to the Bread contract** minus **the total xDai "owed" to BREAD holders**. Thus, what is left over is what can be allocated to the Breadchain projects.

Click [here](https://docs.soliditylang.org/en/v0.8.27/types.html#ternary-operator) for a reference on the ternary operator that is used here.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ternary operators seem pretty standard; this link out feels a bit out of place to me.



Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this file helped me understand the specifics of how BREAD is minted and how the yield is calculated. The conversions between xDai, sDai, and BREAD were helpfully contextualized and mapped to where it actually happens in the codebase.

14 changes: 14 additions & 0 deletions docs/Breadchain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## About Breadchain Cooperative
Breadchain Cooperative is a **collective federation of decentralized cooperative projects** looking to advance a **progressive vision for blockchain** and its effect on society. We aim to do this by building and utilizing what we call *solidarity primitives* - development tools which help to forge solidarity between individuals and collectives.

The first *solidarity primitive* created by the Breadchain Cooperative is the **BREAD** community token created through the [Bread Crowdstaking Application](https://app.breadchain.xyz/). 

The primary infrastructure being built at Breadchain is to ask ourselves ***what if progressives had their own [community currency](https://www.notion.so/What-is-BREAD-f3335ccc7b5142bca578c6d2f2b563d3?pvs=21) and [credit union](https://www.notion.so/Yield-Governance-d3ac44ac679c4756a18e27e5ec0696d5?pvs=21)? Where would we decide to put resources towards to build a post-capitalist political economy?***

## BREAD as a Community Currency
### Consistent value
BREAD is linked to xDAI which is a stablecoin with equal value to USD. So $1 = 1 $BREAD.
### Built on solidarity
A solidarity primitive is a building block for solidarity through code. Build with $BREAD to have a tech stack with values.
### Fund the future
Earnings from the minting of BREAD go to supporting a co-operative of [post-capitalist web3 projects](https://breadchain.notion.site/e92f4f3dfb64402aada35a90bf2712af).
97 changes: 97 additions & 0 deletions docs/ButteredBread.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
```mermaid
classDiagram
class ButteredBread {
<<abstract>> IButteredBread
<<abstract>> ERC20VotesUpgradeable
<<abstract>> OwnableUpgradeable

+static uint256 FIXED_POINT_PERCENT
+IERC20Votes bread
+mapping(address => bool) allowlistedLPs
+mapping(address => uint256) scalingFactors
#mapping(address => mapping(address => LPData)) _accountToLPData

+__constructor__()
+initialize()
+accountToLPBalance()
+syncDelegation()
+deposit()
+withdraw()
+modifyAllowList()
+modifyScalingFactor()
+transfer()
+transferFrom()
+delegate()
#_deposit()
#_withdraw()
#_modifyScalingFactor()
#_syncDelegation()
#_syncVotingWeight()
}

ButteredBread --|> IButteredBread : Inherits
ButteredBread --|> ERC20VotesUpgradeable : Inherits
ButteredBread --|> OwnableUpgradeable : Inherits
```
# Buttered Bread

The ButteredBread contract is designed to enhance liquidity provision and governance participation within the Breadchain ecosystem. At its core, it allows users to deposit Liquidity Pool (LP) tokens, referred to as "Butter," and in return, mint ButteredBread tokens. These ButteredBread tokens represent a scaled version of the deposited LP tokens, with the scaling factor determined for each supported liquidity pool. This mechanism incentivizes users to provide liquidity to specific pools by offering voting power.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are LP tokens something generic, not specific to the BREAD ecosystem? Where do I get my LP tokens from? Any decentralized exchange? For BREAD you mention buying xDai on gnosis chain, so wondering if some similar context can be added here for how someone acquires LP tokens.


A key feature of the ButteredBread contract is its integration with the BREAD token's governance system. While ButteredBread tokens themselves are non-transferable, they inherit the voting power and delegation mechanics of the underlying BREAD token. This is achieved through a unique synchronization process where the ButteredBread contract mirrors the delegation choices made by users in the BREAD token contract. Additionally, the contract allows for dynamic adjustment of scaling factors, enabling the protocol to fine-tune incentives for different liquidity pools over time.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion to improve clarity of last sentence, rewrite like:
"Additionally, the ButteredBread contract allows for dynamic adjustment..."

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My brain would find it helpful to know some examples of these different liquidity pools


## Deposits

```mermaid
sequenceDiagram
actor User
participant BB as ButteredBread
participant LP as Liquidity Pool Token

BB->>LP: deposit(amount)
BB->>LP: approve(address) approve BB to take tokens
User->>BB: deposit(lp, amount)
activate BB
BB->>BB: Check if LP is allowlisted
BB->>LP: transferFrom(user, this, amount)
BB->>BB: Update user's LP balance
BB->>BB: Calculate ButteredBread to mint
BB->>BB: Mint ButteredBread tokens
BB->>BB: Sync delegation
BB-->>User: Deposit complete
deactivate BB
```
1. User calls deposit function with LP address and amount.
2. The contract checks if the LP is allowlisted.
3. It transfers LP tokens from the user to the contract.
4. Updates the user's LP balance in the contract's storage.
5. Calculates the amount of ButteredBread tokens to mint based on the scaling factor.
6. Mints the calculated amount of ButteredBread tokens to the user.
7. Syncs the user's delegation based on their delegation in the $BREAD contract

## Withdrawals
```mermaid
sequenceDiagram
actor User
participant BB as ButteredBread
participant LP as Liquidity Pool Token

User->>BB: withdraw(lp, amount)
activate BB
BB->>BB: Check if LP is allowlisted
BB->>BB: Check if user has sufficient balance
BB->>BB: Sync delegation
BB->>BB: Sync voting weight
BB->>BB: Update user's LP balance
BB->>BB: Calculate ButteredBread to burn
BB->>BB: Burn ButteredBread tokens
BB->>LP: transfer(user, amount)
BB-->>User: Withdrawal complete
deactivate BB
```

1. User calls `withdraw` function with LP address and amount.
2. The contract checks if the LP is allowlisted.
3. It checks if the user has sufficient balance to withdraw.
6. Updates the user's LP balance in the contract's storage.
8. Burns the calculated amount of ButteredBread tokens from the user.
9. Transfers the LP tokens back to the user.
Loading