Skip to content

Commit

Permalink
chore: balancer CoW AMM milestone
Browse files Browse the repository at this point in the history
  • Loading branch information
wei3erHase authored Jun 21, 2024
2 parents e9edf1f + 99f6910 commit 8a60ea2
Show file tree
Hide file tree
Showing 45 changed files with 3,258 additions and 557 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/newBFactory.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3811528
3528278
2 changes: 1 addition & 1 deletion .forge-snapshots/newBPool.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3567680
3315258
1 change: 1 addition & 0 deletions .forge-snapshots/settlementCoWSwap.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
186763
1 change: 1 addition & 0 deletions .forge-snapshots/settlementCoWSwapInverse.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
196603
2 changes: 1 addition & 1 deletion .forge-snapshots/swapExactAmountIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
107618
81507
1 change: 1 addition & 0 deletions .forge-snapshots/swapExactAmountInInverse.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
91166
14 changes: 6 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ jobs:
- name: Install dependencies
run: yarn --frozen-lockfile --network-concurrency 1

- name: Create mock files with smock
run: yarn smock

- name: Precompile using 0.8.14 and via-ir=false
run: yarn build

Expand Down Expand Up @@ -61,17 +58,14 @@ jobs:
- name: Install dependencies
run: yarn --frozen-lockfile --network-concurrency 1

- name: Create mock files with smock
run: yarn smock

- name: Precompile using 0.8.14 and via-ir=false
run: yarn build

- name: Run tests
run: yarn test:integration

lint:
name: Lint Commit Messages
name: Static Analysis
runs-on: ubuntu-latest

steps:
Expand All @@ -95,4 +89,8 @@ jobs:
- name: Install dependencies
run: yarn --frozen-lockfile --network-concurrency 1

- run: yarn lint:check
- name: Run forge-fmt && solhint
run: yarn lint:check

- name: Run natspec-smells
run: yarn lint:natspec 2>&1 >/dev/null | grep 'No issues found'
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,3 @@ broadcast/*/*/*

# Out dir
out

# Smock dir
test/smock
5 changes: 2 additions & 3 deletions .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
"avoid-low-level-calls": "off",
"constructor-syntax": "warn",
"func-visibility": ["warn", { "ignoreConstructors": true }],
"no-inline-assembly": "off",
"ordering": "warn",
"private-vars-leading-underscore": ["warn", { "strict": false }],
"quotes": "off",
"one-contract-per-file": "warn",
"TODO": "REMOVE_TEMPORARY_LINTER_SETTINGS_BELOW",
"style-guide-casing": ["warn", { "ignoreEvents": true } ],
"custom-errors": "off"
"style-guide-casing": ["warn", { "ignoreEvents": true } ]
}
}
3 changes: 2 additions & 1 deletion .solhintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
test/smock/*
test/smock/*
test/manual-smock/*
116 changes: 45 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,83 +1,57 @@
<p align=center>
<img width="128px" src="https://balancer-labs.github.io/pebbles/images/pebbles-pad.256w.png" alt="balancer pebbles logo"/>
</p>
<h1 align=center><code>Balancer CoW AMM</code></h1>

<p align="center">
<a href="https://circleci.com/gh/balancer-labs/balancer-core">
<img src="https://circleci.com/gh/balancer-labs/balancer-core.svg?style=svg&circle-token=2f432d0cf2690bec7f215a7738bd1142b97bd9b4" />
</a>
<a href="https://coveralls.io/github/balancer-labs/balancer-core">
<img src="https://coveralls.io/repos/github/balancer-labs/balancer-core/badge.svg?t=7avwwt" />
</a>
<a href="https://www.gnu.org/licenses/gpl-3.0">
<img src="https://img.shields.io/badge/License-GPLv3-green.svg" />
</a>
</p>

<h1 align=center><code>balancer</code></h1>

**Balancer** is an automated **portfolio manager**, **liquidity provider**, and **price sensor**.

Balancer turns the concept of an index fund on its head: instead of a paying fees
to portfolio managers to rebalance your portfolio, you collect fees from traders, who rebalance
your portfolio by following arbitrage opportunities.
**Balancer CoW AMM** is an automated **portfolio manager**, **liquidity provider**, and **price sensor**, that allows swaps to be executed via the CoW Protocol.

Balancer is based on an N-dimensional invariant surface which is a generalization of the constant product formula described by Vitalik Buterin and proven viable by the popular Uniswap dapp.

## 🍂 Bronze Release 🍂

The *🍂Bronze Release🍂* is the first of 3 planned releases of the Balancer Protocol. Bronze emphasizes code clarity for audit and verification, and does not go to great lengths to optimize for gas.

The *❄️Silver Release❄️* will bring many gas optimizations and architecture changes that will reduce transaction overhead and enable more flexibility for managed pools.

The *☀️Golden Release☀️* will introduce a curious new liquidity mechanism to the market.

## Documentation

The full documentation can be found at [https://docs.balancer.finance](https://docs.balancer.finance)


## Development

Most users will want to consume the ABI definitions for BFactory and BPool.
Most users will want to consume the ABI definitions for BPool, BCoWPool, BFactory and BCoWFactory.

This project follows the standard Truffle project structure.
This project follows the standard Foundry project structure.

```
yarn compile # build artifacts to `build/contracts`
yarn testrpc # run ganache
yarn build # build artifacts to `out/`
yarn test # run the tests
```

Tests can be run verbosely to view approximation diffs:

```
yarn test:verbose
```

```
Contract: BPool
With fees
pAi
expected: 10.891089108910892)
actual : 10.891089106783580001)
relDif : 1.9532588879656032e-10)
Pool Balance
expected: 98010000000000030000)
actual : 98010000001320543977)
relDif : 1.3473294888276702e-11)
Dirt Balance
expected: 3921200210105053000)
actual : 3921200210099248361)
relDif : 1.480428360949332e-12)
Rock Balance
expected: 11763600630315160000)
actual : 11763600630334527239)
relDif : 1.6464292361378058e-12)
✓ exitswap_ExternAmountOut (537ms)
```

Complete API docs are available at [https://docs.balancer.finance/smart-contracts/api](https://docs.balancer.finance/smart-contracts/api)


<p align=center>⊙</p>
## Changes on BPool from (Balancer V1)[https://github.com/balancer/balancer-core]
- Migrated to Foundry project structure
- Implementation of interfaces with Natspec documentation
- Replaced `require(cond, 'STRING')` for `if(!cond) revert CustomError()`
- Bumped Solidity version from `0.5.12` to `0.8.25` (required for transient storage)
- Added explicit `unchecked` blocks to `BNum` operations (to avoid Solidity overflow checks)
- Deprecated `Record.balance` storage (in favour of `ERC20.balanceOf(address(this))`)
- Deprecated `gulp` method (not needed since reading ERC20 balances)
- Deprecated manageable pools:
- Deprecated `isPublicSwap` mechanism (for pools to be swapped before being finalized)
- Deprecated `rebind` method (in favour of `bind + unbind + bind`)
- Deprecated exit fee on `unbind` (since the pool is not supposed to have collected any fees)
- Deprecated `BBaseToken` (in favour of OpenZeppelin `ERC20` implementation)
- Deprecated `BColor` and `BBronze` (unused contracts)
- Deprecated `Migrations` contract (not needed)
- Added an `_afterFinalize` hook (to be called at the end of the finalize routine)
- Implemented reentrancy locks using transient storage.

## Features on BCoWPool (added via inheritance to BPool)
- Immutably stores CoW Protocol's `SolutionSettler` and `VaultRelayer` addresses at deployment
- Immutably stores Cow Protocol's a Domain Separator at deployment (to avoid replay attacks)
- Immutably stores Cow Protocol's `GPv2Order.appData` to be allowed to swap
- Gives infinite ERC20 approval to the CoW Protocol's `VaultRelayer` contract
- Implements IERC1271 `isValidSignature` method to allow for validating intentions of swaps
- Implements a `commit` method to avoid multiple swaps from conflicting with each other.
- This is stored in the same transient storage slot as reentrancy locks in order to prevent calls to swap/join functions within a settlement execution or vice versa.
- It's an error to override a commitment since that could be used to clear reentrancy locks. Commitments can only be cleared by ending a transaction.
- Validates the `GPv2Order` requirements before allowing the swap

## Features on BCoWFactory
- Added a `logBCoWPool` to log the finalization of BCoWPool contracts, to be called by a child pool

## Creating a Pool
- Create a new pool by calling `IBFactory.newBPool()`
- Give ERC20 allowance to the pool by calling `IERC20.approve(pool, amount)`
- Bind tokens one by one by calling `IBPool.bind(token, amount, weight)`
- The amount represents the initial balance of the token in the pool (pulled from the caller's balance)
- The weight represents the intended distribution of value between the tokens in the pool
- Modify the pool's swap fee by calling `IBPool.setSwapFee(fee)`
- Finalize the pool by calling `IBPool.finalize()`
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ solc_version = '0.8.25'
libs = ["node_modules", "lib"]
optimizer_runs = 50 # TODO: increase for production and add via-ir
ffi = true
evm_version = 'cancun'
fs_permissions = [{ access = "read-write", path = ".forge-snapshots/"}]

[profile.optimized]
Expand Down
4 changes: 3 additions & 1 deletion natspec-smells.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@

/** @type {import('@defi-wonderland/natspec-smells').Config} */
module.exports = {
include: 'src/**/*.sol'
enforceInheritdoc: false,
include: 'src/**/*.sol',
exclude: 'src/contracts/B(Num|Const).sol',
};
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@
"build": "forge build",
"build:optimized": "FOUNDRY_PROFILE=optimized forge build",
"coverage": "forge coverage --match-contract Unit",
"deploy:mainnet": "bash -c 'source .env && forge script Deploy -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:testnet": "bash -c 'source .env && forge script Deploy -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bcowfactory:mainnet": "bash -c 'source .env && forge script DeployBCoWFactory -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bcowfactory:testnet": "bash -c 'source .env && forge script DeployBCoWFactory -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bfactory:mainnet": "bash -c 'source .env && forge script DeployBFactory -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bfactory:testnet": "bash -c 'source .env && forge script DeployBFactory -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"lint:check": "solhint 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol' && forge fmt --check",
"lint:fix": "solhint --fix 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol' && sort-package-json && forge fmt",
"lint:natspec": "npx @defi-wonderland/natspec-smells --config natspec-smells.config.js",
"prepare": "husky install",
"smock": "smock-foundry --contracts src/contracts",
"test": "forge test -vvv",
"test:integration": "forge test --match-contract Integration -vvv",
"test:integration": "forge test --match-contract Integration -vvv --isolate",
"test:local": "FOUNDRY_FUZZ_RUNS=100 forge test -vvv",
"test:unit": "forge test --match-contract Unit -vvv",
"test:unit:deep": "FOUNDRY_FUZZ_RUNS=5000 yarn test:unit"
Expand All @@ -35,13 +37,15 @@
"package.json": "sort-package-json"
},
"dependencies": {
"@cowprotocol/contracts": "github:cowprotocol/contracts.git#a10f40788a",
"@openzeppelin/contracts": "5.0.2",
"composable-cow": "github:cowprotocol/composable-cow.git#24d556b",
"solmate": "github:transmissions11/solmate#c892309"
},
"devDependencies": {
"@commitlint/cli": "19.3.0",
"@commitlint/config-conventional": "19.2.2",
"@defi-wonderland/natspec-smells": "1.1.1",
"@defi-wonderland/natspec-smells": "1.1.3",
"@defi-wonderland/smock-foundry": "1.5.0",
"forge-gas-snapshot": "github:marktoda/forge-gas-snapshot#9161f7c",
"forge-std": "github:foundry-rs/forge-std#5475f85",
Expand Down
5 changes: 4 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ ds-test/=node_modules/ds-test/src
forge-std/=node_modules/forge-std/src
forge-gas-snapshot/=node_modules/forge-gas-snapshot/src
solmate/=node_modules/solmate/src
@cowprotocol/=node_modules/@cowprotocol/contracts/src/contracts
cowprotocol/=node_modules/@cowprotocol/contracts/src/
@composable-cow/=node_modules/composable-cow/

contracts/=src/contracts
interfaces/=src/interfaces
interfaces/=src/interfaces
17 changes: 17 additions & 0 deletions script/DeployBCoWFactory.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {BCoWFactory} from 'contracts/BCoWFactory.sol';
import {Script} from 'forge-std/Script.sol';
import {Params} from 'script/Params.s.sol';

contract DeployBCoWFactory is Script, Params {
function run() public {
BCoWFactoryDeploymentParams memory _params = _bCoWFactoryDeploymentParams[block.chainid];

vm.startBroadcast();
BCoWFactory bCoWFactory = new BCoWFactory(_params.settlement, _params.appData);
bCoWFactory.setBLabs(_params.bLabs);
vm.stopBroadcast();
}
}
7 changes: 3 additions & 4 deletions script/Deploy.s.sol → script/DeployBFactory.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
pragma solidity 0.8.25;

import {BFactory} from 'contracts/BFactory.sol';
import {Params} from 'script/Params.s.sol';

import {Script} from 'forge-std/Script.sol';
import {Params} from 'script/Params.s.sol';

contract Deploy is Script, Params {
contract DeployBFactory is Script, Params {
function run() public {
DeploymentParams memory _params = _deploymentParams[block.chainid];
BFactoryDeploymentParams memory _params = _bFactoryDeploymentParams[block.chainid];

vm.startBroadcast();
BFactory bFactory = new BFactory();
Expand Down
27 changes: 22 additions & 5 deletions script/Params.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,35 @@
pragma solidity 0.8.25;

contract Params {
struct DeploymentParams {
struct BFactoryDeploymentParams {
address bLabs;
}

/// @notice Deployment parameters for each chain
mapping(uint256 _chainId => DeploymentParams _params) internal _deploymentParams;
struct BCoWFactoryDeploymentParams {
address bLabs;
address settlement;
bytes32 appData;
}

/// @notice Settlement address
address internal constant _GPV2_SETTLEMENT = 0x9008D19f58AAbD9eD0D60971565AA8510560ab41;

/// @notice AppData identifier
bytes32 internal constant _APP_DATA = bytes32('appData');

/// @notice BFactory deployment parameters for each chain
mapping(uint256 _chainId => BFactoryDeploymentParams _params) internal _bFactoryDeploymentParams;

/// @notice BCoWFactory deployment parameters for each chain
mapping(uint256 _chainId => BCoWFactoryDeploymentParams _params) internal _bCoWFactoryDeploymentParams;

constructor() {
// Mainnet
_deploymentParams[1] = DeploymentParams(address(this));
_bFactoryDeploymentParams[1] = BFactoryDeploymentParams(address(this));
_bCoWFactoryDeploymentParams[1] = BCoWFactoryDeploymentParams(address(this), _GPV2_SETTLEMENT, _APP_DATA);

// Sepolia
_deploymentParams[11_155_111] = DeploymentParams(address(this));
_bFactoryDeploymentParams[11_155_111] = BFactoryDeploymentParams(address(this));
_bCoWFactoryDeploymentParams[11_155_111] = BCoWFactoryDeploymentParams(address(this), _GPV2_SETTLEMENT, _APP_DATA);
}
}
21 changes: 21 additions & 0 deletions src/contracts/BCoWConst.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.25;

/**
* @title BCoWConst
* @notice Constants used in the scope of the BCoWPool contract.
*/
contract BCoWConst {
/**
* @notice The value representing the absence of a commitment.
* @return _emptyCommitment The commitment value representing no commitment.
*/
bytes32 public constant EMPTY_COMMITMENT = bytes32(0);

/**
* @notice The largest possible duration of any AMM order, starting from the
* current block timestamp.
* @return _maxOrderDuration The maximum order duration.
*/
uint32 public constant MAX_ORDER_DURATION = 5 * 60;
}
Loading

0 comments on commit 8a60ea2

Please sign in to comment.